Dan Henry
Guru
  
Reged: Oct 16 2003
Posts: 4597
Loc: Colorado
|
|
I read the PICC' readme's, but regarding the Limitations/Preprocessor section, I'll admit that I have glossed over the "Incorrect result for sizeof" entry until just now. Shame on me.
Now having read it and paying attention, I read a distinction being made between the sizeof operator in a preprocessor context versus a 'C' context. I was not aware that the preprocessor had any notion whatsoever about a sizeof operator. Before I ask on comp.lang.c and get my tail handed to me between my legs for me to tuck, I thought I'd ask here first: - What is the sizeof preprocessor operator?
- How does it differ (other than as stated in the readme) from the C sizeof operator?
|
jtemples
Guru
  
Reged: Oct 16 2003
Posts: 2000
Loc: Southern California
|
|
It's a Hi-Tech extension, so asking about it on c.l.c. would probably have unfortunate consequences.
|
Dan Henry
Guru
  
Reged: Oct 16 2003
Posts: 4597
Loc: Colorado
|
|
Thanks, that saved some embarrassment. I have now found sizeof mentioned in the preprocessor context in the manuals' "Error and Warning Messages" section to infer how it's used. Has the extension ever been documented in the "C Language Features" section (or elsewhere for that matter)?
|
Gerhard
Reged: Apr 21 2004
Posts: 89
Loc: Brazil
|
|
A little bit late here, but my take on this is that the sizeof preprocessor statement is used inside preprocessor statements, whereas the sizeof C language construct is used everywhere else. I have never seen (consciously ) a documentation of it.
|
G.Neiss
  
Reged: Dec 26 2004
Posts: 474
Loc: germany
|
|
And this kind of implemetation (in HI-TECH C) is of less usabiality, because it doesn't work for typedef's. So I don't know what it is god for.
In Borland C I am able to use something like this:
Code:
typedef struct { } TDocuRecord; #define Sizeof_TDocuRecord 123
#if sizeof( TDocuRecord ) > 256 #error sizeof( TDocuRecord ) > 256 #endif
This is (for ex.) to enshure that a type fits into one bank. This doesn't work in HI-TECH C , because the preprocessor doesn't know the type at this point (in oposite to Borland C, which handles this correct).
|
Gerhard
Reged: Apr 21 2004
Posts: 89
Loc: Brazil
|
|
I don't know what you find so superior in the Borland C implementation. The corresponding Hi-Tech C code would look like this (and also works): Code:
typedef struct { } TDocuRecord; #define Sizeof_TDocuRecord 123
#if Sizeof_TDocuRecord > 256 #error Sizeof_TDocuRecord > 256 #endif
The problem that both compilers share here is that the size of the defined struct has to be maintained manually. That's likely to get out of sync at one point or another.
The real deal would, of course, be: Code:
typedef struct { } TDocuRecord;
#if sizeof( TDocuRecord ) > 256 #error sizeof( TDocuRecord ) > 256 #endif
|
John Payson
  
Reged: Oct 16 2003
Posts: 1336
|
|
Many compilers, the HiTech one included, will evaluate some constant expressions at compile time. Curiously, certain error checks seem to be done before compilation is complete. Nonetheless, the following seems to be a workable approach to crash the build for the 14-bit PICs if something is not an expected size though it does generate some wasted code (there's no need for the code to actually execute): Code:
unsigned char foo[1]; /* Could use any array I think */ if (foo[6-sizeof(THINGIE)] || foo[sizeof(THINGIE)-6]) ;
If the size of THINGIE is 6, this will access the first byte of foo twice. Otherwise, the negative subscript will cause a link error.
|
Gerhard
Reged: Apr 21 2004
Posts: 89
Loc: Brazil
|
|
Quote:
If the size of THINGIE is 6, this will access the first byte of foo twice. Otherwise, the negative subscript will cause a link error.
Link error or compile error?
I use this sometimes (I think this is based on an idea of yours): Code:
#define CTASSERT( aCheck, aMax ) \ /* Creates compile error if aCheck exceeds aMax */\ { volatile u8 dummy; dummy = 1 / ((aMax) / (aCheck)); }
Would be interesting to compare the code overhead. For an == check, two CTASSERTs are necessary. If often used, that could of course be put into a separate macro.
|
lucky
Microchip staff
   
Reged: Oct 06 2003
Posts: 1212
Loc: Brisbane, Australia
|
|
Quote:
And this kind of implemetation (in HI-TECH C) is of less usabiality, because it doesn't work for typedef's.So I don't know what it is god for.
It doesn't know about more complex types at the preprocessor stage, but it does know the size of basic types. This allows you to do things such as: Code:
#if sizeof(unsigned int) == 2 typedef unsigned int uint16_t #endif
Or,
#if sizeof(double) != 4 #error 32-bit double floating point required #endif
So, if it occurs within a #if, it is done by the preprocessor, in all other cases it is done later, at code generation time. The limitation to this (as described in the readme) is that the preprocessor won't necessarily know the correct size of pointers. This is particularly the case for PRO compilers, since pointer size may vary based on your program requirements.
|
John Payson
  
Reged: Oct 16 2003
Posts: 1336
|
|
Quote:
Quote:
If the size of THINGIE is 6, this will access the first byte of foo twice. Otherwise, the negative subscript will cause a link error.
Link error or compile error?
Link error, curiously enough. It seems like the compiler does its constant-array-bounds checking before it finishes evaluating all constant expressions, so constant expressions which evaluate to invalid array bounds may not be flagged.
|