We have following code
int main()
{
void f() throw(int);
f();
return 0;
}
void f() { }
GCC and clang compiles it well. But, in standard there is such paragraph:
n3376 15.4/4
If any declaration of a function has an exception-specification that is not a noexcept-specification allowing
all exceptions, all declarations, including the definition and any explicit specialization, of that function shall have a compatible exception-specification.
And for following example: gcc - error, clang - warning
void f() throw(int);
int main()
{
f();
return 0;
}
void f() { }
Why there is difference in these snippets? Thanks.
The n3376 15.4/4 from the std specifie that all déclarations and definitions of a function must have the same throwing type. Here :
void f() throw(int);
int main()
{
f();
return 0;
}
void f() { }
the declaration void f() throw(int); and the definition void f() { } are in global scop. So they are in conflict because the declaration is for a function which throw int while the definition is for a function without a throw specification.
Now, when you put the declaration in the main scop, the definition isn't in the same scop, during this scop the definition isn't known so you can compile.
I hope you understood my english, sorry about it.
Related
I hope a quick small question to those who tried C++20 modules
According to TS, should this code compile in C++20?
void f1() { f2(); }
void f2() { ... }
For example, in C++11 it won't compile, because f1() doesn't "know" about the f2(), f2() must be declared before usage.
But maybe in C++20 this requirement will be eliminated in modules?
If the first code snippet is not compiled, will this one compile
void f1() { f2(); }
export void f2() { ... }
because f2() will be seen from the BMI?
While Modules does change many things about name lookup (the latest paper I'm aware of is P1103R1), Modules will not change the fundamental property of C++ that names must be declared before use (modulo things like dependent unqualified calls - which simply delays the lookup, but it still has to actually happen).
This:
void f1() { f2(); }
export void f2() { ... }
will still be a compile error if there is no previous declaration of f2 or it wasn't imported from somewhere. You'll have to write:
export void f2() { ... }
void f1() { f2(); }
Single File Example
Here is a simple program using namespaces.
#include <iostream>
namespace foo {
void hello();
}
void foo::hello() {
std::cout << "hello\n";
}
void foo::hello(); // Why is this syntax allowed? When is it useful?
int main() {
foo::hello();
}
This program compiles fine and produces the expected output.
$ ./a.out
hello
I want to know when is the void foo::hello(); declaration useful? In this program, clearly this declaration is redundant. But since this syntax exists, this must be useful in some other scenario?
Two-File Example
Here is an example that shows that the void foo::hello(); declaration standing alone is useless.
// foo.cpp
#include <iostream>
namespace foo {
void hello();
}
void foo::hello() {
std::cout << "foo::hello\n";
}
// main.cpp
void foo::hello(); // This does not work!
int main()
{
foo::hello();
}
Trying to compile the above two files leads to the following errors:
$ clang++ foo.cpp main.cpp
main.cpp:1:6: error: use of undeclared identifier 'foo'
void foo::hello();
^
main.cpp:5:5: error: use of undeclared identifier 'foo'
foo::hello();
^
2 errors generated.
The only way to fix main.cpp in the above example seems to be include the namespace declaration:
// main.cpp - fixed
namespace foo {
void hello();
}
void foo::hello(); // But now this is redundant again!
int main()
{
foo::hello();
}
So after we get this code to compile properly, the void foo::hello(); declaration seems redundant again. Is there any scenario where such a declaration would be playing a useful role?
In most cases in C++, for anything that can be either declared without defining it or can be completely defined, a declaration or a definition of that thing can appear in all the same contexts. So this is probably just a way of keeping the pattern consistent.
The C++ Standard does not go out of its way to forbid things that are a logical consequence of its other rules but just not useful, as long as it's reasonably clear what will happen if someone does it anyway. If it did add these restrictions, that would put extra work on compiler writers for no real benefit.
From [basic.def]/1
A declaration may introduce one or more names into a translation unit or redeclare names introduced by previous declarations. If so, the declaration specifies the interpretation and attributes of these names.
Which allows code like this
#include <iostream>
void foo();
void foo();
void foo();
void foo();
void foo();
int main()
{
foo();
}
void foo() { std::cout << "foo()"; }
To be valid. There is no harm in having multiple declarations of a function, as long as we have only one definition, it won't cause an issue.
Another example would be you have a global function you want to be a friend of multiple classes. You would include that function prototype in each class header so you can friend it and then you would include all of those class headers in your main source file. So
A.h
void foo();
struct A { friend void foo(); }
B.h
void foo();
struct B { friend void foo(); }
main.cpp
#include "A.h"
#include "B.h"
...
and that would be converted to
main.cpp
void foo();
struct A { friend void foo(); }
void foo();
struct B { friend void foo(); }
...
So we would want this to be legal.
This seems a bit strange to me. Since a static method can have an instance of the class, one naturally expects that the compiler should not allow calling static methods inside the constructor. But I have tested the following code with every compiler and ironically, none of them gave me a single warning. Although in execution time they all throw exceptions. Am I missing something here?
#include <iostream>
class Foo
{
public:
inline Foo()
{
std::cout << "testing: var = " << bar() - 1 << '\n';
}
~Foo(){}
static int bar()
{
Foo f;
f.var = 10;
return f.test();
}
private:
int var;
int test()
{
return var + 1;
}
};
int main()
{
Foo foo;
return 0;
}
Live example
It is not illegal to call static functions from within the constructor. Only, you are getting a stack overflow, if you do it like you do. This results in
Foo() calls bar();
bar() calls Foo();
Foo() calls bar();
bar() calls Foo();
...
Until no stack is left.
This is exactly the same as if you had:
void f1();
void f2()
{
f1();
}
void f1()
{
f2();
}
int main(int, char*[])
{
f1();
return 0;
}
Only two global functions, nothing more. Would have been all the same in C, too (but you have do declare void f(void) there), or Java, C#, perl, python, ...
What warnings are you expecting? What you've written is an infinite recursion which has nothing to do with static member functions. You can do it with any other function inside or outside a class.
Static functions are not much different from the free ones. So free functions should also be banned from constructor? There is no point in forbidding to call static functions from constructors.
There is no reason not to call a static (or in fact a non-static) member function in a constructor (although it is not recommended to call virtual functions).
namespace A {
void F() {}
namespace B {
void F(int) {}
}
}
using A::B::F;
namespace A {
void G() {
F(); // OK
F(1); // Error: too many arguments to function void A::F()
}
}
int main() { return 0; }
I have this piece of code.
I defined two functions with same names but different signatures.
Then I use a using-declaration using A::B::F.
In A::G() compiler tries to resolve A::F() before A::B::F().
Are there any orders if there are such conflicts?
The deepest nested scope is searched first, and scopes are then searched outward if the name is not found. So first it would find a block-scope declaration of F inside G, if any; then it would find a declaration at the namespace scope of A, if any; and if that too failed it would search the global scope. Since using A::B::F; appears at global scope, A::F is always found first. Perhaps you should move the using declaration inside A.
It's definitely about placement.
namespace A {
void G() {
F(); // OK, A::F
using B::F;
F(1); // OK, A::B::F
}
}
Why does the following code prints different results on different compilers?
#include <iostream>
void foo() { std::cout << "::foo() \n"; }
namespace Foo
{
struct Bar
{
friend void foo() { std::cout << "Bar::foo() \n"; }
void bar() { foo(); }
void baz();
};
void Bar::baz() { foo(); }
}
int main()
{
Foo::Bar instance;
instance.bar();
instance.baz();
}
Output
gcc 4.7.2
::foo()
::foo()
MSVC-10.0
Bar::foo()
Bar::foo()
MSVC-11.0
error C3861: 'foo': identifier not found
error C3861: 'foo': identifier not found
Who is right? And why is it so?
I think gcc is right:
7.3.1.2/3 in C++11:
If a friend declaration in a non-
local class first declares a class or function the friend class or
function is a member of the innermost enclosing namespace. The name of
the friend is not found by unqualified lookup (3.4.1) or by qualified
lookup (3.4.3) until a matching declaration is provided in that
namespace scope (either before or after the class definition
C++03 has similar language in the same place.
I'm not sure why MSVC-11 fails to find ::foo, but I suppose you could read this text to mean that the name foo can't be looked up at all. I think the intended meaning is that the name in the innermost enclosing namespace can't be found, but the identically-spelled name in the outer scope can. But if Microsoft wants to argue the intended meaning I'm not the person they'd argue it with.
MSVC-10 is wrong, because it found a name that the standard specifically says is not found. So the explanation for the MSVC-11 behavior might be as simple as "it was reported as a bug in 10, they tried to fix it and went too far".
Anyway, the fix is to introduce a declaration of foo in namespace Foo:
namespace Foo
{
void foo(); // this is a matching declaration
struct Bar
{
friend void foo() { std::cout << "Bar::foo() \n"; }
void bar() { foo(); }
void baz();
};
void Bar::baz() { foo(); }
}
This makes gcc find the friend function. I haven't tested on any version of MSVC.