471,086 Members | 1,451 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,086 software developers and data experts.

Why this code must add sizeof()?

Hello Everybody
In <<Modern C++ Design>Compile-Time Assertions
there is :
template <boolstruct CompileTimeChecker
{
CompileTimeChecker(...);
};

template <struct CompileTimeChecker<false{ };

#define STATIC_CHECK(expr,msg) \
{ \
class ERROR_##msg {}; \
(void)sizeof( CompileTimeChecker< (expr) !=
0>( (ERROR_##msg() ) )); \
}
//.....
so my question is why " (void)sizeof( CompileTimeChecker< (expr) !=
0>( (ERROR_##msg() ) )); \" must add sizeof?
Thanks

Apr 9 '07 #1
11 2805
nevergone wrote:
so my question is why " (void)sizeof( CompileTimeChecker< (expr) !=
0>( (ERROR_##msg() ) )); \" must add sizeof?
Thanks
Sizeof is a handy function used in these kinds of macros because
it causes the syntax of the expression to be checked but never
actually evaluates the expression.

Apr 9 '07 #2
On Apr 9, 2:08 pm, "nevergone" <wyx2006s...@gmail.comwrote:
so my question is why " (void)sizeof( CompileTimeChecker< (expr) != 0>( (ERROR_##msg() ) )); \" must add sizeof?
in general, checks for incomplete types are better done within sizeof
because it's runtime overheads are minimum. try to generate the
assembly code (using, g++ -S) with and without the "sizeof" and you'll
see that the sizeof version is better.

however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.

---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
int main(){ STATIC_CHECK(1>2,mustFail);}
/* end code */
---

here's what g++ gives me:

---
g++ -Wall -pedantic test.cpp
test.cpp: In function `int main()':
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
---

apart from that warning, the compilation goes through.
shouldn't it fail? what am i missing?

thanks,
--
#1 - pg. 21, Modern C++ Design, Andrei Alexandrescu.

Apr 9 '07 #3
On 4月9日, 下午8时34分, "aiooua" <aio...@gmail.com>wrote:
On Apr 9, 2:08 pm, "nevergone" <wyx2006s...@gmail.comwrote:
so my question is why " (void)sizeof( CompileTimeChecker< (expr) != 0>( (ERROR_##msg() ) )); \" must add sizeof?

in general, checks for incomplete types are better done within sizeof
because it's runtime overheads are minimum. try to generate the
assembly code (using, g++ -S) with and without the "sizeof" and you'll
see that the sizeof version is better.

however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.

---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
int main(){ STATIC_CHECK(1>2,mustFail);}
/* end code */
---

here's what g++ gives me:

---g++ -Wall -pedantic test.cpp

test.cpp: In function `int main()':
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
---

apart from that warning, the compilation goes through.
shouldn't it fail? what am i missing?

thanks,
--
#1 - pg. 21, Modern C++ Design, Andrei Alexandrescu.
I don't know.
but i think it would be better to add () in 1>2

Apr 9 '07 #4
nevergone wrote:
On 4月9日, 下午8时34分, "aiooua" <aio...@gmail.comwrote:
>On Apr 9, 2:08 pm, "nevergone" <wyx2006s...@gmail.comwrote:
>>so my question is why " (void)sizeof( CompileTimeChecker< (expr) != 0>( (ERROR_##msg() ) )); \" must add sizeof?
in general, checks for incomplete types are better done within sizeof
because it's runtime overheads are minimum. try to generate the
assembly code (using, g++ -S) with and without the "sizeof" and you'll
see that the sizeof version is better.

however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.

---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
int main(){ STATIC_CHECK(1>2,mustFail);}
/* end code */
---

here's what g++ gives me:

---g++ -Wall -pedantic test.cpp

test.cpp: In function `int main()':
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
---

apart from that warning, the compilation goes through.
shouldn't it fail? what am i missing?

thanks,
--
#1 - pg. 21, Modern C++ Design, Andrei Alexandrescu.
I don't know.
but i think it would be better to add () in 1>2
It's not necessary to add () in 1>2 except for readability reasons
(arguably since some people consider more () to be less readable). In
the macro, 'expr' is already guarded by ().

I found the code example confusing, it almost seemed like it should do a
sizeof(CompileTimeChecker<(expr)>) != 0 test instead. It may be trying
to facility the empty structure optimization, an empty struct/class's
sizeof returns 0 as the specialization template<struct
CompileTimeChecker<false{ }; would do.

Fei
Apr 9 '07 #5
i got the same problem with aiooua
but if i took off the sizeof function
the code could work,but it seems that the compiler took the code
"CompileTimeChecker< (expr) >( (ERROR_##msg() ) )"
as a function declaration instead of a temporary object
here is my test code :

#include <iostream>
using namespace std ;
template <boolstruct CompileTimeChecker
{
CompileTimeChecker(...) { cout << "constructor" << endl ; }
};
template <struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr,msg) \
{ \
class ERROR_##msg {}; \
CompileTimeChecker< (expr) >( (ERROR_##msg() ) ); \
}
int main()
{
STATIC_CHECK( true , error ) ;
return 0 ;
}
can anybody explain it ?

Apr 10 '07 #6
On Mon, 09 Apr 2007 07:51:25 -0400, Ron Natalie <ro*@spamcop.net>
wrote in comp.lang.c++:
nevergone wrote:
so my question is why " (void)sizeof( CompileTimeChecker< (expr) !=
0>( (ERROR_##msg() ) )); \" must add sizeof?
Thanks
Sizeof is a handy function used in these kinds of macros because
it causes the syntax of the expression to be checked but never
actually evaluates the expression.
sizeof is NOT a function, it is an operator.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Apr 10 '07 #7
i think i got the answer:
suppose you have a class : class a { public : a(){} } ;
when you write the code : a() ;
the compiler can explain this in two ways:
1. a temporary object of type a
2. a function declaration of type a (*)(void)
so , in order to distinguish this you can use sizeof
which can not take a function type as a parameter
in order to tell sizeof that which you pass is a type
you have to add additional ()
so ,if you write sizeof( ( a() ) ) , the compiler will understand
that
a() is a temporary object

Apr 10 '07 #8
On Apr 9, 2:34 pm, "aiooua" <aio...@gmail.comwrote:
On Apr 9, 2:08 pm, "nevergone" <wyx2006s...@gmail.comwrote:
so my question is why " (void)sizeof( CompileTimeChecker< (expr) != 0>( (ERROR_##msg() ) )); \" must add sizeof?
in general, checks for incomplete types are better done within sizeof
because it's runtime overheads are minimum. try to generate the
assembly code (using, g++ -S) with and without the "sizeof" and you'll
see that the sizeof version is better.
however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.
---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
I'm not sure about the exact error message you got---it seems a
little strange. But this line is definitly illegal; for
starters, it contains a } for which there is no {. And ##
operators are only legal in macros.

Are you sure you didn't forget a \ at the end of the previous
line? This line would make sense as part of the macro.
int main(){ STATIC_CHECK(1>2,mustFail);}
/* end code */
---
here's what g++ gives me:
---g++ -Wall -pedantic test.cpp
test.cpp: In function `int main()':
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
Which, as I say, is wierd. The only way a compiler could
possibly parse the sizeof here is as part of an expression
statement. (But of course, expression statements are not legal
at namespace scope.)

Note that if you did mean for this line to be part of the macro,
the line number in the error message should tip you off
immediately about the forgotten \. You never get error messages
from continuation lines in a macro. (Just error messages from
where you invoke the macro.)
---
apart from that warning, the compilation goes through.
shouldn't it fail? what am i missing?
Probably just an \.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient閑 objet/
Beratung in objektorientierter Datenverarbeitung
9 place S閙ard, 78210 St.-Cyr-l'蒫ole, France, +33 (0)1 30 23 00 34

Apr 10 '07 #9
On Apr 10, 8:34 pm, "James Kanze" <james.ka...@gmail.comwrote:
On Apr 9, 2:34 pm, "aiooua" <aio...@gmail.comwrote:
however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.
---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
Are you sure you didn't forget a \ at the end of the previous
line? This line would make sense as part of the macro.
the macro was well-formed when i compiled, it got wrapped into two
lines (maybe because of line-length limits or something) while i
posted it here.
I'm not sure about the exact error message you got---it seems a
unlike what the book says, and what i expected i did not get any
error.
however, i got the following warning.

--
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
--

it seemed too simple to be a g++ bug, but i'll follow it on their
newsgroup.

thanks,

Apr 11 '07 #10
aiooua wrote:

unlike what the book says, and what i expected i did not get any
error.
however, i got the following warning.

--
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
--

it seemed too simple to be a g++ bug, but i'll follow it on their
newsgroup.
The ISO C++ standard does not mandate "warnings" or "errors". Certain
conditions require a diagnostic. A warning is a diagnostic. It is quite
possible for a compiler to decide to continue with compilation,
especially if operating in a non-conforming mode so that it applies
various extensions.

Brian
Apr 11 '07 #11
On Apr 11, 6:58 am, "aiooua" <aio...@gmail.comwrote:
On Apr 10, 8:34 pm, "James Kanze" <james.ka...@gmail.comwrote:
On Apr 9, 2:34 pm, "aiooua" <aio...@gmail.comwrote:
however, i have a related, but different problem. i tried the code as
printed in the book[#1] and couldn't get it to work.
---
/* begin code */
template<boolstruct CompileTimeChecker{ CompileTimeChecker(...); };
template<struct CompileTimeChecker<false{ };
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {};
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))); }
Are you sure you didn't forget a \ at the end of the previous
line? This line would make sense as part of the macro.
the macro was well-formed when i compiled, it got wrapped into two
lines (maybe because of line-length limits or something) while i
posted it here.
You mean that the line following the #define was actually on the
same line?

The reason I asked is because when I added the \ to the end of
the line with the #define, the code worked as expected (i.e.
failed to compile). (Of course, without the \, it failed to
compile as well.)
I'm not sure about the exact error message you got---it seems a
unlike what the book says, and what i expected i did not get any
error.
however, i got the following warning.
--
test.cpp:4: warning: ISO C++ forbids applying `sizeof' to a function
type
--
If I add the \ to the end of the line, I get:
cerr.cc: In function 'int main()':
cerr.cc:5: error: invalid application of 'sizeof' to a function
type
from g++. Both with no options, and with my usual options.
Maybe you have set some option somewhere to make g++ treat this
as a warning only.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient閑 objet/
Beratung in objektorientierter Datenverarbeitung
9 place S閙ard, 78210 St.-Cyr-l'蒫ole, France, +33 (0)1 30 23 00 34

Apr 12 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by DiskMan | last post: by
14 posts views Thread by nullptr | last post: by
12 posts views Thread by syn1kk | last post: by
8 posts views Thread by Wayne Shu | last post: by
9 posts views Thread by onkar | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.