This code appears to break on one widely used compiler with optimizations enabled, although it works fine in Visual Studio.
struct foo
{
foo(int a) { s[0] = '0'+a%10;s[1] = '\0'; }
const char * bar() const { return &s[0]; }
char s[4];
};
int main( )
{
const char * s = foo(1234).bar();
printf("%p %s\n", s, s);
}
I expect that even though foo is an rvalue, that it will be constructed on the stack, and 's' will point to valid data. However, with GCC (versions 7.5 and 9), the buffer is never initialized.
Example failing compile line:
g++-9 --std=c++11 -Wall -pedantic -O3 -o example example.cpp
On this line:
const char * s = foo(1234).bar();
s
is pointing to the char s[4]
member of a temporary foo
object. At the end of the full expression, this object dies, and s
is now pointing to invalid memory. Printing it on the next line will invoke undefined behavior.
The issue here is with the use of the return value of bar()
. The chained function call itself is fine, so if you use the expression directly in the printf
it's well-defined:
printf("%s\n", foo(1234).bar()); // ok
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With