Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ One-liner. Is it legal to construct an object and call a function on the same line

Tags:

c++

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
like image 265
A4April Avatar asked Mar 02 '23 02:03

A4April


1 Answers

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
like image 105
cigien Avatar answered Mar 15 '23 23:03

cigien