![]() |
| | #1 |
| Registered User Join Date: Jun 2008
Posts: 4
| preprocessor help I´m trying to create a routine to validate my casting. What I want to do is if my structure size is right put some code, if the code should report an error. Does anyone knows how can I do this at compile time? Code: #define COMPILE_TIME_ASSERT(test, a) \
#if (test == 1) \
*(char*)&(a)\
#else\
"Structure size error!"\
#endif
#define BYTE(a) COMPILE_TIME_ASSERT(sizeof(a) == 1, a)
int main
{
char a,b;
b = BYTE(a);
BYTE(a) = a+1;
return a;
}
|
| brunogon is offline | |
| | #2 |
| Deathray Engineer Join Date: Mar 2007
Posts: 3,211
| Try something like this in your #else construct: Code: #error "Structure size error!"\
__________________ Last edited by MacGyver; 06-16-2008 at 08:29 AM. |
| MacGyver is offline | |
| | #3 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| No, you can't. "sizeof()" is done later during the compile than the preprocessor, so you can't do that. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #4 |
| Technical Lead Join Date: Aug 2007 Location: London, UK
Posts: 723
| The Preprocessor is just a dumb search-and-replace tool. It doesn't evaluate the code in any way. f you need to validate a sizeof() you'll need to have the compiler do it for you. QuantumPete
__________________ "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support "Have you tried turning it off and on again?" - The IT Crowd |
| QuantumPete is offline | |
| | #5 |
| Registered User Join Date: Jun 2008
Posts: 4
| So far, I think It is getting the sizeof correctly, the problem is if has any way to define my #define COMPILE_TIME_ASSERT(test, a) with a preprocessor #if. As the #if gives me an error, I also tryied use (test) ? *(char*)&(a) : "error"; despite it compiles okay, it add the whole code on the define and not just the *(char*)&(a) or "error" |
| brunogon is offline | |
| | #6 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| I don't think this sort of thing can be done in C, or at least not easily. However, it can be done easily in C++.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #7 |
| Registered User Join Date: Jun 2008
Posts: 1,134
| |
| C_ntua is offline | |
| | #8 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| Psuedo code, but... Something along the lines of: Code: int main()
{
char mychar;
int myint;
char* c = safe_cast<char>(mychar); // Compiles
c = safe_cast<char>(myint); // Won't compile
}
template<typename NewType, typename OriginalType>
NewType& safe_cast(Original& Data)
{
STATIC_ASSERT(sizeof(NewType) == sizeof(OriginalType));
return (NewType)Data;
}
There are more ways to do this, of course, but this is the easy way. I haven't checked if this will compile, so it may contain a few errors, but the theory is sound. And in you don't want to use boost, you can just the compiler to complain. Something like: Code: int main()
{
char mychar;
int myint;
char* c = safe_cast<char>(mychar); // Compiles
c = safe_cast<char>(myint); // Won't compile
}
template<bool bFail>
struct dummy { static const bool bFail; };
template<>
struct dummy<true> { static const bool bFail = 'a'; }; // Causes a compile error about conversion from char to bool on purpose
template<>
struct dummy<false> { static const bool bFail = false; };
template<typename NewType, typename OriginalType>
NewType& safe_cast(Original& Data)
{
dummy< sizeof(NewType) != sizeof(OriginalType) >::bFail;
return (NewType)Data;
}
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
Last edited by Elysia; 06-16-2008 at 10:32 AM. | |
| Elysia is offline | |
| | #9 |
| Registered User Join Date: Jun 2008
Posts: 1
| A workaround I've used before is something like: Code: #define COMPILE_ASSERT(_cond) typedef char _Dummy[(_cond)] Code: int main()
{
COMPILE_ASSERT(sizeof(char) == 1);
}
Code: #define COMPILE_ASSERT(_cond) typedef char _Dummy[(_cond) - 1] |
| Balbanes is offline | |
| | #10 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
So, you have to use regular if-statements to make the compiler see what you want. If it's even a little bit clever, it will then optimize away your test all together unless it's failing, and if it fails, then it will produce ONLY the code to perform your error message. I presume Elysia is referring to the template meta-programming stuff you can do in C++, where templates ARE expanded at compile time when sizeof() and such is known to the compiler. -- Mats -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #11 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| Indeed. It's potent stuff.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
Last edited by Elysia; 06-16-2008 at 10:48 AM. | |
| Elysia is offline | |
| | #12 |
| Registered User Join Date: Jun 2008
Posts: 4
| Thanks everybody, Unfortunately I can´t use C++ code, I was trying to do some decent cast validation, but I think it is not possible. Tks again for your help |
| brunogon is offline | |
| | #13 |
| Registered User Join Date: Jun 2008
Posts: 4
| Anyway, If I try implement this during execution, and not at the preprocessor, would it be possible? Any ideas? I would need something that makes posbile to use it exactly as *(char*)&(a). I mean a = safe_cast(b), safe_cast(b) = a Cheers Last edited by brunogon; 06-16-2008 at 11:13 AM. |
| brunogon is offline | |
| | #14 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| It would be possible at runtime, yes. Perhaps you can use... if (sizeof(a) != sizeof(b)) abort(); ...type of macro. It's runtime, but it's better than nothing. (C++ can do it compile time.)
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
![]() |
| Tags |
| compile, preprocessor |
| Thread Tools | |
| Display Modes | |
|