tags:

views:

188

answers:

5
+1  Q: 

Ambiguous Syntax

#include <iostream>
using namespace std;

typedef int MYINT;

int main() 
{ 
    int y = MYINT();                     // As expected, y = 0; value initialization
    cout << MYINT();                     // Error
    cout << sizeof(MYINT());             // Error
} 

Why the last two lines in the main function before the closing brace give error? Why is the expression MYINT() treated differently in different contexts? Any Standard reference will be helpful.

+5  A: 

If your MINTINT is typedef int MYINT then MYINT() is not a function but is int() which is a default initialization, equivallent to int y = 0 or int y = int(0).

Your second line, ie cout << MYINT() compiles correctly for me with g++ -Wall -ansi -pedantic for the same reason.

But g++ will complain for the sizeof with the following error error: invalid application of "sizeof" to a function type because it interprets MYINT() as "a call to a default constructor for int" (EDIT: this is not correct) "a function type returning MYINT which is not allowed" (EDIT: this is the correct answer, see Mike's). But this a nothing to do with the typedef.

Summary:

#include <iostream>
typedef int myint;
int main()
{
int y = myint();
int z = myint(0);
std::cout << y << z; // Will output 0 0
std::cout << std::endl << myint(0) << myint(); // Will output 0 0
std::cout << sizeof(int()); // The error is here; same with sizeof(myint())
}

Edit (again)

As said in the comment is the cout lines doesn't work for you, this is because you probably forgot to include <iostream>.

Edit Look also the answer of Mike Seymour for an explanation of the ambiguity with sizeof.

Cedric H.
You need to explain why a value initialized temporary isn't valid (if it isn't) in the other two lines.
Charles Bailey
@Charles: Edited my post.
Cedric H.
Why sizeof interpret int() as a function, but not a temporary valuable?
lz_prgmr
See the answer of Mike Seymour.
Cedric H.
@Dbger: When there is an ambiguity over whether something is an expression or a type specifier, it will be interpreted as a type specifier (in this case, a function type).
Mike Seymour
"The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered as type-id" ---- from C++ standard, that it because type-id is of high priority
lz_prgmr
@Mike Seymour sorry, I didn't notice your reply first. That is how C++ defined, thanks.
lz_prgmr
So cout << sizeof(MYINT(1)) won't be a problem as it doesn't like an type specifier anymore
lz_prgmr
Indeed `sizeof(int(1))` works.
Cedric H.
Ints do not have a "default constructor". So this is a wrong answer, but delegates to the correct answer by @Mike. Yet, it's upvoted to +7 while @Mike's answer is at +3. Weird!
Johannes Schaub - litb
Mike is correct, that's why I mentioned his answer, third Mike's answer came after mine, that's why I guess I have more upvotes... To be completely fair I corrected the answer to reflect that.
Cedric H.
+2  A: 

Why the last two lines in the main function before the closing brace give error?

cout << MYINT(); doesn't work because cout is not defined. Once you do #include <iostream> and using std::cout, it will work fine.

sizeof(MYINT()) does indeed not work, but sizeof(int()) doesn't work either, so that's to be expected. sizeof(MYINT) will work just fine.

Why is the expression MYINT() treated differently in different contexts?

It's not. In every case MYINT() behaves exactly like int().

sepp2k
+1 for there is no need to define MYINT to show the same results
lz_prgmr
+3  A: 
// OK. Implicit conversion to int.
int y = MYINT();          

// OK. Implicit conversion again. Which compiler do you use?
cout << MYINT();          

// Invalid. Tries to get size of a function that returns MYINT,
// because sizeof expects a type-id and according to 8.2/2,
// which is forbidden according to the C++ Standard 5.3.3/1
cout << sizeof(MYINT());  
// Do you want this instead?
cout << sizeof(MYINT);  
Kirill V. Lyadvinsky
+7  A: 

MYINT() can, depending on context, be interpreted as an expression of type MYINT, or a specifier of a function type taking no arguments and returning MYINT. In some situations, where either an expression or a type specifier is valid, this gives an ambiguity; this is resolved by interpreting it as a type specifier if possible (EDIT: C++03 8.2/2, if you want a Standard reference).

sizeof can take either an expression, or a parenthesised type specifier, as it's argument, giving this ambiguity. So here MYINT() is interpreted as a type specifier; then you get an error, since sizeof can't be applied to a function type.

EDIT: You can fix the error by removing the parentheses so it will be interpreted as an expression (sizeof MYINT()), adding extra parentheses so it isn't a valid type specifier (sizeof((MYINT()))), or changing it to the correct type (sizeof(MYINT)).

cout << MYINT() is unambiguous, so there should be no error, and indeed there isn't on my compiler. What is the error, and what is your compiler?

Mike Seymour
+1. May be worthwhile to show a work around. One such is to say `sizeof MYINT()` or `sizeof((MYINT()))`
Johannes Schaub - litb
@Mike Seymour: Indeed there is no error on cout << MYINT() on a second confirmation on my system as well!. Sorry for the misleading info
Chubsdad
+1  A: 

I do not see any error for the cout << MYINT(); line. However I see invalid application of 'sizeof' to a function type for the cout << sizeof(MYINT()); line. The problem is the () around MYINT(). The C++ standard says this about sizeof and how it is parsed:

sizeof unary-expression
sizeof ( type-id )

There is a parsing ambiguity between sizeof unary-expression and sizeof ( type-id ). It is resolved by using longer match. It parses sizeof (MYINT()) as sizeof ( type-id ), MYINT() is a function type and thus you see the error.

wilx