$ g++ -O2 -Wall test.cc
test.cc: In function ‘int main()’:
test:8: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing
rules
/usr/include/c++/4.4/bits/stl_list.h:214: note: initialized from here
I don’t see anything suspicious in the following program, but there
should be a reason for the warning. Can anyone explain this?
/* 1 */ #include <list>
/* 2 */
/* 3 */ struct X
/* 4 */ {
/* 5 */ struct P
/* 6 */ {
/* 7 */ const void* p;
/* 8 */ bool operator==(const P& o) const { return p == o.p; }
/* 9 */ };
/* 10 */
/* 11 */ typedef std::list<P> PL;
/* 12 */
/* 13 */ struct I
/* 14 */ {
/* 15 */ PL::const_iterator itr;
/* 16 */ bool operator==(I o) const { return *itr == *o.itr; }
/* 17 */ bool operator!=(I o) const { return !(*this == o); }
/* 18 */ I& operator++() { ++itr; return *this; }
/* 19 */ };
/* 20 */
/* 21 */ PL list;
/* 22 */
/* 23 */ I begin() const { I i = {list.begin()}; return i; }
/* 24 */ I end() const { I i = {list.end()}; return i; }
/* 25 */ };
/* 26 */
/* 27 */ int main()
/* 28 */ {
/* 29 */ X x;
/* 30 */ for (X::I it = x.begin(); it != x.end(); ++it) { }
/* 31 */ }
Line 214 of /usr/include/c++/4.4/bits/stl_list.h looks like this:
/* 182 */ /**
/* 183 */ * @brief A list::const_iterator.
/* 184 */ *
/* 185 */ * All the functions are op overloads.
/* 186 */ */
/* 187 */ template<typename _Tp>
/* 188 */ struct _List_const_iterator
/* 189 */ {
/* ... */
/* 210 */ // Must downcast from List_node_base to _List_node to get to
/* 211 */ // _M_data.
/* 212 */ reference
/* 213 */ operator*() const
/* 214 */ { return static_cast<_Node*>(_M_node)->_M_data; }
/* ... */
/* 260 */ };
$ g++ --version
g++ (Debian 4.4.2-9) 4.4.3 20100108 (prerelease)
Copyright (C) 2009 Free Software Foundation, Inc.
...
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
> I get this warning while compiling the program below with g++-4.4.3:
>
> $ g++ -O2 -Wall test.cc
> test.cc: In function ‘int main()’:
> test:8: warning: dereferencing pointer ‘<anonymous>’ does break
> strict-aliasing rules
> /usr/include/c++/4.4/bits/stl_list.h:214: note: initialized from here
>
> I don’t see anything suspicious in the following program, but there
> should be a reason for the warning. Can anyone explain this?
I get the same with gcc-4.4.3 built for Cygwin on Windows. However,
what seems strange is that I apparently can avoid this warning simply by
building in two separate steps:
21:27:45 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPPM $gcc -Wall -c test.cc
21:27:58 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPPM $g++ -O2 test.o
<snip>code - see OP</snip>
>
> $ g++ --version
> g++ (Debian 4.4.2-9) 4.4.3 20100108 (prerelease)
> Copyright (C) 2009 Free Software Foundation, Inc.
> ...
21:28:16 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPPM $g++ --version
g++ (GCC) 4.4.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Regards
Paul Bibbings
--
{ edits: quoted sig & banner removed. please keep readers in mind when you
quote. -mod }
With gcc 4.4.1 I am not able to reproduce the issue:
jyoti@vbox:~$ g++ --version
g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
jyoti@vbox:~$ g++ -Wall --pedantic test.cpp -o test
jyoti@vbox:~$ ./test
jyoti@vbox:~$
Understanding strict aliasing might help:
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
Regards,
Jyoti
That’s because you omitted -O2 when you were compiling; specifically,
-O2 turns on -fstrict-aliasing. As far as I know, -fstrict-aliasing
affects the compiling stage, not the linking stage, so what you’re
doing is basically turning off -fstrict-aliasing, which is why you’re
not getting the warning.
Turning off that optimization could be an answer, but I’d like to know
whether the warning is just a false positive or it really means I risk
some undefined behaviour and I should do something (turn the optimization
off or change the code somehow).
--
Seungbeom Kim
Did you try -O2 or -fstrict-aliasing? It is crucial that you turn it on.
> Understanding strict aliasing might help:
> http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
I know what strict aliasing is, and had read that article too, but
it doesn't help me understanding this particular case.
--
Seungbeom Kim
"does" means you *are* violating the rules. g++ says "may" (IIRC, maybe
"can") when it can't figure out for sure.
I think there are different levels of strict aliasing checking. See
the manpage.
FWIW, I just disable strict aliasing on all C++ code I write. AFAICT,
strict aliasing was for C, g++ is just (incorrectly?) applying it to
C++. Further, these aliasing concerns are exactly why we have the
valarray header, and so it seems dumb in C++: if it was critical for
performance that my data didn't alias, I would use valarray. If I'm
not, then why would my compiler assume my variables didn't alias?
I've never brought this up on gcc-help; it's possible I'm missing
something.
-tom
--
There is no cast, therefore there should be no problem.
Report this issue to the GCC guys.
--
Actually there is one at stl_list.h:214, though that is just a downcast
and I doubt it should actually be a problem.
--
Seungbeom Kim
INCITS+ISO+IEC+14882-2003
C++03 standard.
3.10 Lvalues and rvalues / 15
If a program attempts to access the stored value of an object through
an lvalue of other than one of the following
types the behavior is undefined48):
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the
dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-
qualified version of the dynamic type of
the object,
— an aggregate or union type that includes one of the aforementioned
types among its members (including,
recursively, a member of a subaggregate or contained union),
— a type that is a (possibly cv-qualified) base class type of the
dynamic type of the object,
— a char or unsigned char type.
__________________
48) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.