I wrote the following code:
#include <iostream>
using namespace std;
int main()
{
int v()
return 0;
}
I ran it in ideone, and it compiled successfully. I have the same code in file test1.cpp on my computer, I ran g++ test1.cpp and I got the following error:
./test1.cpp: In function ‘int main()’:
./test1.cpp:7:2: error: a function-definition is not allowed here before ‘return’
Why dose this happen? is this a bug?
I'm using linux mint, gcc version 4.7.
You are missing a semi-colon here:
int v()
^
should be:
int v() ;
which is a function declaration, not clear that was what was intended though. If you want to initialize v then the following would work:
int v(0) ;
or in C++11:
int v{0} ;
This is commonly known as C++'s most vexing parse. When you do something like
int f();
the compiler reads this as a function prototype, declaring a function f that returns an int. If you're using C++11, you should instead do
int f{}; // f initialized to 0
if you're not using C++11, make sure to initialize the variable right away.
You forgot the semicolon after
int v();
Ideone is using gcc 4.8.1 for your code (as you can see in your own link) while you are using 4.7
There are several difference regarding C++ 11 implementation, and apparently it is affected by the line that looks like a function delcaration.
Related
I'm trying to compile the following C++ code on Visual Studio Code, using the Mac clang compiler.
#include <iostream>
int main() {
int x { 5 };
std::cout << x;
return 0;
}
However, this returns an error, on the line of the list initialization: int x{ 5 };. Specifically, it says I need to insert a semicolon after the x.
I don't get what's wrong with this code, it works fine on an online compiler. How do I fix this?
Running man clang in the Terminal and skimming through, I found this:
The default C++ language standard is gnu++14.
UPDATE: I ran clang++ main.cpp in the compiler and it returned that semicolon error. This isn't a problem with VSCode, so I'll remove that tag.
Here's the error:
main.cpp:3:10: error: expected ';' at end of declaration
int x { 5 };
^
;
1 error generated.
Consider following code:
run on gcc.godbolt.org
#include <initializer_list>
struct A
{
int x;
};
int main()
{
std::initializer_list<A>{100};
}
Clang accepts it. GCC and MSVC reject it, with errors like:
error: no matching function for call to 'std::initializer_list<A>::initializer_list(<brace-enclosed initializer list>)'
Which compiler is correct here?
I tried looking at [dcl.init.list]/5 and [over.match.list], but didn't find anything interesting.
The following code compiles just fine and I'm not sure why. Can someone please explain to me why this is legal?
I am using g++ (Debian 6.1.1-10) 6.1.1 20160724 to compile.
#include <iostream>
int sum(int x, int y) { return x + y; }
int main(int argc, char *argv[])
{
using std::cout;
int (*) (int, int) = ∑
cout << "what" << '\n';
}
Addendum
The following program compiles fine using g++ version 5.4.0 but fails to compile in gcc.
int main()
{
int (*) = 20;
}
It's very likely to be related to this bug reported by Zack Weinberg:
Bug 68265 - Arbitrary syntactic nonsense silently accepted after 'int (*){}' until the next close brace
(From Why does this invalid-looking code compile successfully on g++ 6.0? :)
The C++ compiler fails to diagnose ill-formed constructs such as
int main()
{
int (*) {}
any amount of syntactic nonsense
on multiple lines, with *punctuation* and ++operators++ even...
will be silently discarded
until the next close brace
}
With -pedantic -std=c++98 you do get "warning: extended initializer
lists only available with -std=c++11 or -std=gnu++11", but with
-std=c++11, not a peep.
If any one (or more) of the tokens 'int ( * ) { }' are removed, you do
get an error. Also, the C compiler does not have the same bug.
Of course, if you try int (*) (int, int) {} or other variants, it erroneously compiles. The interesting thing is that the difference between this and the previous duplicate/bug reports is that int (*) (int, int) = asdf requires asdf to be a name in scope. But I highly doubt that the bugs are different in nature, since the core issue is that GCC is allowing you to omit a declarator-id.
[n4567 §7/8]: "Each init-declarator in the init-declarator-list
contains exactly one declarator-id, which is the name declared by
that init-declarator and hence one of the names declared by the
declaration."
Here's an oddity:
int (*) (int, int) = main;
In this specific scenario, GCC doesn't complain about taking the address of main (like arrays, &main is equivalent to main).
I have a simple program containing the following code:
namespace nam
{
struct S{};
void f(S *){}
}
void f(nam::S *){}
int main()
{
nam::f(nullptr);
nam::S s;
f(&s);
return 0;
}
I expect that this will compile fine because I am calling f the second time without specifying namespace nam. However, upon compiling the code, I get this error:
$ g++ main.cpp -std=c++11 -Wall -Wextra
main.cpp: In function ‘int main()’:
main.cpp:14:9: error: call of overloaded ‘f(nam::S*)’ is ambiguous
f(&s);
^
main.cpp:7:6: note: candidate: void f(nam::S*)
void f(nam::S *){}
^
main.cpp:4:10: note: candidate: void nam::f(nam::S*)
void f(S *){}
Compiler and version:
$ gcc --version
gcc (Debian 5.3.1-14) 5.3.1 20160409
After trying this with different compilers, similar errors are returned. This seems to be a defined part of C++. I can't find anywhere on the internet where it says that calling a function with a struct in namespace nam as a parameter effectively implies using namespace nam; and requires ::f to remove ambiguity. I have 2 questions about this:
Where is this defined in the C++ standard?
Is there a good reason for this behavior?
Personally I like to avoid using namespace x; and similar. I want the compiler to give me an error when I don't specify a namespace. This behavior stops the compiler from doing so, and this means my code is inconsistent in places, because I occasionally forget to specify the namespace when calling functions like f that are not declared globally anywhere.
Your implementation of f(nam::S*) is outside of the namespace of 'nam'
change:
void f(nam::S *){}
to:
void nam::f(nam::S *){}
(or just move the enclosing namespace bracket) and all should be fine.
if your call to f(&s) in the current namespace was intentional then you need to specify this by changing the function call to
::f(&s)
As was said in the comments, this is due to argument-dependent lookup. I guess now I'll have to figure out now if I want to always specify the namespace in my code where this would make it unnecessary, or never specify it.
As the title mentioned. The following code shows error :
#include <iostream>
using namespace std;
class link
{
public:
link()
{
num=0;
next=NULL;
}
int num;
link* next;
};
int main() {
link test;
return 0;
}
compile this code with
g++ test.cpp -o test
my g++ versions is
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
And the compiler shows the following error
test.cpp: In function ‘int main()’:
test.cpp:18:10: error: expected ‘;’ before ‘test’
If I comment this 'link test' statement, then everything is ok.
Besides, if I replace 'link' with other name like 'Link', everything is ok too.
In Visual Studio or VC, the code is ok.... So it confused me very much.
To summarize the comments:
GCC includes a function named link. For C compatibility, C++ allows you to define a struct (or class) with the same name as a function, but you have to disambiguate them on use.
I.e. in this case, the fix is class link test;
The use of link inside the definition of class link is an exception, there it always refers to the class itself. This is necessary to be able to write the constructor, as you can't disambiguate the name there. There's no syntax which would allow it.
There is a int link(const char *path1, const char *path2); function in unistd.h, which appears to be included from iostream. Gcc has had some problems with this kind of problem in the past. (I note that 4.7.2 doesn't show this behavior.)
As noted by MSalters, adding a
class link test;
should disambiguate the problem.