In C++11, according to en.cppreference.com,
For signed and non-negative a, the value of a << b is a * 2b if it is representable in the return type, otherwise the behavior is undefined.
My understanding is that, since 255 * 224 is not
representable as an int32_t, the evaluation of (int32_t) 255 << 24
yields undefined behavior. Is that correct? Can this be
compiler-dependent? It's an IP16 environment, if that matters.
Background: this comes from an argument I am having with a user at arduino.stackexchange.com. According to him, “there's nothing undefined about that at all”:
you notice that much of the bit shifting is "implementation defined". So you cannot quote chapter-and-verse from the specs. You have to go to the GCC documentation since that is the only place that can tell you what actually happens. gnu.org/software/gnu-c-manual/gnu-c-manual.html#Bit-Shifting - it's only "undefined" for a negative shift value.
Edit: From the answers so far, it would seem my reading of the C++11 standard is correct. Then the key part of my question is whether this expression invokes undefined behavior in gcc. As davmac puts it in his comment, I am asking “whether GCC, an implementation, defines a behaviour even though it is left undefined by the language standard”.
From the gcc manual I linked to, it would seem it is indeed defined, although I find the wording of this manual sounds more like a tutorial than a “language law”. From PSkocik's answer (and Kane's comment to that answer), it would instead seem it is undefined. So I am still in doubt.
I guess my dream would be to have a clear statement in some gcc documentation stating either that 1) gcc does not define any behavior that is explicitly undefined in the standard or, 2) gcc does define this behavior from version XX.XX and commits to keep it defined in all subsequent versions.
Edit 2: PSkocik deleted his answer, which I find unfortunate because it provided interesting information. From his answer, Kane's comment to the answer, and my own experiments:
(int32_t)255<<24produces a runtime error when compiled with clang and-fsanitize=undefined- the same code produces no error with g++ even with
-fsanitize=undefined (int32_t)256<<24does give a runtime error when compiled withg++ -std=c++11 -fsanitize=undefined
Point 2 is consistent with the interpretation that gcc, in C++11 mode,
defines the left shift more broadly than the standard. As per point 3,
this definition could just be the C++14 definition. However, point 3 is
inconsistent with the idea that the referenced manual is a
complete definition of << in gcc (C++11 mode), as that manual provides
no hint that (int32_t)256<<24 could be undefined.