D
Denis Remezov
Rob said:Peter Ammon wrote in
in comp.lang.c++:
Here's some short code that exhibits my problem.
--
#include <cstdlib>
using namespace std;
#define CMAX (sizeof (((trie_node*)NULL)->children) \
/ sizeof *(((trie_node*)NULL)->children))
class trie_node {
trie_node* children[26];
enum { cmax = 26 };
trie_node *children[ cmax ];
public:
unsigned child_count(void) const {
unsigned i, result=0;
for (i=0; i < CMAX; i++) {
if (children) result++;
}
return result;
}
};
[...]
--
gcc 3.3 emits this warning:
test.cpp: In member function `unsigned int trie_node::child_count()
const': test.cpp:11: warning: invalid access to non-static data member
`
trie_node::children' of NULL object
Is gcc right to complain? I thought arguments to sizeof are not
evaluated.
Its neither right or wrong, dereferencing a NULL ponter is Undefined
Behaviour (UB).
gcc has detected the UB and issued a warning, but anything it
chooses to do is Ok (as far as the Standard is concerned).
I don't think that this is the case here.
The compiler warns of the expression
((trie_node*)NULL)->children
(twice)
However, since both this and the expression *<the_above> are operands
of sizeof, they are never evaluated. In particular, there is no
dereferencing or access to data as the compiler thinks. Everything
is well defined here.
I've noticed an interesting detail: if you convert trie_node to a POD
(just make all members public), the warnings will go away. I thought
this might have something to do with the compiler attempting
to control the usage of the offsetof macro, which is only defined
for PODs.
Denis