Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is 'int x = + "foo";' a type error but not a syntax error?

Tags:

c++

All compilers I tried correctly reject the code

int main() {
  int x = "foo";
}

with a type error: const char[4] cannot be converted to int. Why is it that the same compilers (including Ideone.com) give the same error for

int main() {
  int x = + "foo";
}

instead of (as I would have thought) a syntax error becaus of the + sign? My first idea was that const char[4] decays to a pointer, which in turn is treated as an integral value so the + denotes "positive". Seems a little far-fetched though, and I would have expected to see const char* appear in the error message.

like image 972
Frerich Raabe Avatar asked Dec 03 '14 15:12

Frerich Raabe


4 Answers

Syntax doesn't involve types in the type system sense (ints and chars and pointers), only types in the syntactic sense of keywords, operators, expressions. In C++ syntax, + is a unary prefix operator that can precede an expression. "foo" is an expression. Therefore, +"foo" is a valid expression as far as the parser is concerned.

Your idea that the string constant decays into a pointer and + is a no-op on pointers is correct, and the following program even compiles and runs:

#include <iostream>

int main()
{
    const char *message = +"Hello!\n";
    std::cout << message;
}

... but that's irrelevant. What you're seeing is a type error, not a syntax error.

EDIT Perhaps even more convincing is the fact that you can overload unary +:

#include <iostream>

struct SomeType {
    const char *operator+() const
    {
        return "Hello, world!\n";
    }
};

int main()
{
    SomeType x;
    std::cout << +x;
}
like image 172
Fred Foo Avatar answered Nov 18 '22 09:11

Fred Foo


Unary + applies to pointers and it just returns the value of the type and does not perform integral promotions on pointers so the result is a pointer not an integral type, from the draft C++ standard section 5.3.1 Unary operators:

The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. The type of the result is the type of the promoted operand.

a string literal is an array of const char, from 2.14.5 String literals:

[...]A narrow string literal has type “array of n const char”,[...]

which will decay to pointer in this context.

like image 24
Shafik Yaghmour Avatar answered Nov 18 '22 10:11

Shafik Yaghmour


The unary + operator can be applied to pointer types:

C++11 5.3.1 [expr.unary.op]/7: The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument.

So the literal array is converted to const char *, and the operator applied to that pointer, before failing to assign the pointer to an int just as in the first example.

like image 7
Mike Seymour Avatar answered Nov 18 '22 09:11

Mike Seymour


Why is 'int x = + “foo”;' a type error but not a syntax error?

Because there is no syntax error. There is a semantic error.

After parsing the statement the compiler determines whether such initialization is posiible. In fact syntaxically the statement looks like

int x = + ( expression );

Syntaxically this statement is correct. Moreover the unary plus may be applied to pointers.

like image 4
Vlad from Moscow Avatar answered Nov 18 '22 10:11

Vlad from Moscow