Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio C++ compiler weird behaviour

I'm just curious to know why this small piece of code compiles correctly (and without warnings) in Visual Studio. Maybe the result is the same with GCC and Clang, but unfortunately I can't test them now.

struct T {
    int t;
    T() : t(0) {}
};

int main() {
    T(i_do_not_exist);
    return 0;
}
like image 546
c.bear Avatar asked Dec 22 '15 13:12

c.bear


People also ask

Is Visual Studio good for C?

Yes, you very well can learn C using Visual Studio. Visual Studio comes with its own C compiler, which is actually the C++ compiler. Just use the . c file extension to save your source code.

Is Visual Studio better than GCC?

In the question“What are the easiest to use C++ compilers and IDEs?” Microsoft Visual C++ is ranked 2nd while GCC is ranked 3rd. The most important reason people chose Microsoft Visual C++ is: To get C++ running on a build machine, just copy the VC bin, and all the headers/libraries you'll need.

Is Visual Studio A good C++ compiler?

Microsoft Visual Studio is a good compiler for developing Windows applications.


2 Answers

T(i_do_not_exist); is an object declaration with the same meaning as T i_do_not_exist;.

N4567 § 6.8[stmt.ambig]p1

There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

§ 8.3[dcl.meaning]p6

In a declaration T D where D has the form

( D1 )

the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration

T D1

Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

like image 120
cpplearner Avatar answered Oct 25 '22 11:10

cpplearner


Because it defines a variable of type T:

http://coliru.stacked-crooked.com/a/d420870b1a6490d7

#include <iostream>

struct T {
    int t;
    T() : t(0) {}
};

int main() {
    T(i_do_not_exist);
    i_do_not_exist.t = 120;
    std::cout << i_do_not_exist.t;
    return 0;
}

The above example looks silly, but this syntax is allowed for a reason.

A better example is:

int func1();
namespace A
{
   void func1(int);
   struct X {
       friend int (::func1)();
   };
}

Probably other examples could be found.

like image 23
marcinj Avatar answered Oct 25 '22 10:10

marcinj