Hi guys,
I have a piece of code that I copied from another source but I don't understand what it means and the Keil compiler doesn't either.
The code looks like that:
#if _MSC_VER >= 1000 #define __CIFx_PACKED_PRE #endif typedef __CIFx_PACKED_PRE struct DRIVER_INFORMATIONtag { char abDriverVersion[32]; uint32_t ulBoardCnt; } __CIFx_PACKED_POST DRIVER_INFORMATION;
I get this error message for this typedef statement:
cifXUser.h(236): warning: #260-D: explicit type is missing ("int" assumed) cifXUser.h(236): error: #65: expected a ";"
And acutally I haven't seen a typedef like this before... in my opinion a typedef should look like something without the "__CIFx_PACKED_PER" part.
Can you help me in configuring the compiler right (so that it compiles that) and could you tell me, what it is about here?
Thanks a lot!!!
Maybe you are missing a
#include <stdint.h>
no, that didn't change anything :)
Some compilers have extra keywords outside the language standard.
So for some operating systems, you may have to use these extra keywords as attributes to get the compiler to generate special code - maybe for a calling convention used by the OS.
In that case, the preprocessor may check what environment the code is compiled for. If compiled for an environment where this extra attribute is needed, then the code has a
#if defined(SPECIAL_CALLING_CONVENTION) #define MY_CALLING_CONVENTION_KEYWORD __bloody_fast_call #else #define MY_CALLING_CONVENTION_KEYWORD #endif ... void MY_CALLING_CONVENTION the_function(void) { }
On an environment where SPECIAL_CALLING_CONVENTION is defined, the compiler will see:
void __bloody_fast_call the_function(void) { }
On an environment where SPECIAL_CALLING_CONVENTION isn't defined, the compiler will see:
void the_function(void) { }
If checking around, you could find Microsoft include files where function prototypes looks like:
WINBASEAPI DWORD WINAPI GetCurrentThreadId( VOID );
So WINBASEAPI and WINAPI can expand to target-specific extra goodies when needed.
And you might be able to find things like:
/* Define __cdecl for non-Microsoft compilers */ #if ( !defined(_MSC_VER) && !defined(__cdecl) ) #define __cdecl #endif /* Define _CRTAPI1 (for compatibility with the NT SDK) */ #ifndef _CRTAPI1 #if _MSC_VER >= 800 && _M_IX86 >= 300 #define _CRTAPI1 __cdecl #else #define _CRTAPI1 #endif #endif
In your case, the issue was a structure. In the general case, it's the compiler that "owns" the memory layout of a struct. So the compiler may have one or more specific attributes to allow a user to select a specific packing for the structure. Should it be packed for maximum speed, with potentially a lot of padding between fields to make sure that things match up depending on data type sizes and maybe even in modulo relation to processor cache line sizes.
Or maybe the compiler should pack all struct members to smallest size, with zero padding even if that makes all members larger than 1 potentially misaligned.
Or maybe the compiler has a pack attribute to select pack to 16-bit or 32-bit align.
Your sample code looks like it was written to take into account some such special packing instruction depending on what compiler that was used.
So if a define has only one argument the compiler will remove this in the code. That's good to know and yes: I will read my textbook again. It's has been a while since I looked into it last time. Thanks Per and Andrew!
One argument?
No #define <name> <expansion data>
or #define <name> (<arg>[,<arg>]) <expansion data>
A #define always has a name of the defined symbol. Then an optional list of arguments. Then what the #define should expand to - and it's allowed to have empty defines that does not have any expansion data.
Remember that #define is a preprocessor concept. It's a glorified search/replace that is done on-the-fly before the compiler processes the source code.
sorry: what I meant by 'argument' was <name>.
So what I actually wanted to state to verify my understanding was:
If there is just a name and no expansion data in the #define, then the compiler will just remove that name in the sourcecode while preprocessing.
View all questions in Keil forum