Strange output with static objects - c++

I can't understand what's happening...
Suppose that I have the following code:
// main.cpp
#include "some_header.h"
void bar();
int main()
{
foo();
bar();
}
// file.cpp
#include "some_header.h"
void bar()
{
foo();
}
// some_header.h
#include "foo.h"
inline
void foo()
{
static Foo instance;
}
// foo.h
#include <iostream>
class Foo
{
public:
Foo() { std::cout << "Foo::Foo() \n"; }
~Foo() { std::cout << "Foo::~Foo() \n"; }
};
Output
Foo::Foo()
Foo::~Foo()
The question is: why there's no second "Foo::Foo()" in the output? I think that it should be here because each translation unit (in my case main.cpp and file.cpp) should have its own Foo object (because of static keyword). Am I wrong? Can somebody quote the standard, please?
If i move the definition of Foo object from the function like this
// some_header.h
#include "foo.h"
static Foo instance;
inline
void foo()
{
}
the output will be
Foo::Foo()
Foo::Foo()
Foo::~Foo()
Foo::~Foo()
Is it inline magic or am I missing smth more fundamental?
What I need to do - I need to add boost::mutex object in some function for my header-only library to synchronize some WinAPI function calls like this:
inline
void some_func()
{
static boost::mutex sync;
boost::lock_guard<boost::mutex> lock(sync);
// Call some WinAPI function
}
How can I do it?
MSVC-11.0.

static is a heavily overloaded keyword in C++. At namespace scope, it means "entity has internal linkage, so every translation unit will have its own copy." At function scope, it means "there is only one such entity for the function and it persists across function calls."
So in your case, the funcion foo() simply has one object Foo instance with local scope, but global lifetime.
As for your mutex question, I can't see anything wrong with doing just what you posted in the question. some_func() will have a single instance of the mutex, and all calls to some_fucn() will share that one instance (and since C++11, it will be correctly and thread-safely initialised by the first such call). I'd say that's exactly what you need.

Related

When is a namespace::function() declaration useful?

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.

Calling static methods in constructor

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).

calling same name function

Is it possible to call foo() function from Foo.cpp
without changing function name Foo::foo() to Foo::newfoo().
main.cpp
#include <iostream>
#include "Foo.hpp"
class Foo {
public:
void foo() {
std::cout << "Foo::foo\n";
}
void bar() {
std::cout << "Foo::bar\n";
foo();// need to call foo() function from foo.cpp not Foo::foo()
}
};
int main () {
Foo f;
f.bar();
return 0;
}
Foo.hpp
#ifndef FOO_HPP_INCLUDED
#define FOO_HPP_INCLUDED
void foo();
#endif // FOO_HPP_INCLUDED
Foo.cpp
#include "Foo.hpp"
#include <iostream>
void foo(){
std::cout << "foo\n";
}
ps.sorry for my poor english.
Use fully qualified name of the free function.
::foo();
The :: in front of the function name, tells the compiler to call the function by the name foo() that is in the global scope.
If the free function foo() was in some other namespace you need to use fully qualified name specifying the namespace.
namespacename::foo();
If the free function foo is defined in some namespace xyz, then do this:
xyz::foo(); //if foo is defined in xyz namespace
or else just do this:
::foo(); //if foo is defined in the global namespace
This one assumes foo is defined in the global namespace.
It is better to use namespace for your implementation. Avoid polluting the global namespace.

c++ singleton initialization order

I have
class Foo
class Bar
Now, I want
Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();
to both initialize before
int main()
is called.
Furthermore, I want
Foo::singleton
to initialize before
Bar::singleton
Is there anyway I can ensure that?
Thanks!
Global variables (like the singletons) that are defined in the same translation unit are initialized in the order in which they are defined. So put the definition of both singletons in the same source file, in the correct order.
If they would be defined in different source files the order in which they are initialized would be unspecified (the "static initialization order fiasco").
See also Static variables initialisation order
For gcc use init_priority:
http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
Works across different translation units. So your code would read:
Foo* Foo::singleton __attribute__ ((init_priority (2000))) = new Foo();
Bar* Bar::singleton __attribute__ ((init_priority (3000))) = new Bar();
I don't have gcc handy right now so I can't verify this, but I have used it before.
The other simpler and more portable solution is to avoid static initialization, and explicitly create the singletons in order at some well defined place within main.
// Nothing in static area
void main(void)
{
// Init singletons in explicit order
{
Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();
}
// Start program execution
...
}
Remember, things will get just as gnarly with singletons on the way out of the program as well, so its often better to make it explicit.
#include <iostream>
class Foo {
public:
static Foo *singleton ()
{
if (foo == NULL)
foo = new Foo;
return foo;
}
private:
Foo ()
{
std::cout << "Foo()\n";
}
static Foo *foo;
};
Foo *Foo::foo = NULL;
Foo *singleton = Foo::singleton ();
int
main ()
{
std::cout << "main()\n";
return 0;
}
Output:
Foo()
main()
In a nutshell:
// smooth.cpp
#include "foo.h"
#include "bar.h"
Foo* Foo::singleton = new Foo();
Bar* Bar::singleton = new Bar();
A nice syntax, to avoid worrying about that:
Foo& Foo::singleton()
{
static Foo Singleton;
return Singleton;
}
The good thing about this syntax, is that the singleton is initialized at the first call of the method, thus you don't have to worry (usually) when it happens, since when calling the method to access it you get it anyway :)

c++ namespace export

Is there a way in C++ to create an anonymous namespace, and only export a single function out of it?
I want something like:
namespace {
void Bar() {}
void Foo() { Bar(); }
}
Now, I want to somehow access to Foo() yet make sure there's no way to touch Bar()
Thanks!
If you want to export the function, you'll have to put it outside the anonymous namespace.
namespace {
void Bar() {};
};
void Foo() { Bar(); };
Since you want Foo() to have external linkage, you should declare it in a header file:
#ifndef FOO_H
#define FOO_H
void Foo();
#endif
Now everyone can see and call Foo()
But in Foo.cpp:
#include "Foo.h"
namespace {
void Bar(){ }
}
void Foo(){ Bar(); }
Now, as long as you control the source file Foo.cpp, no one can change access to Bar()
You could place them in different header files and make sure clients only get the header file that declares Foo(). However, you cannot implement Foo() inline with that solution.
why not
namespace {
void Bar() {};
};
void Foo() { Bar(); };
?
an anonymous namespace is accessible from the file you created it in
Define Bar as a global static function in the CPP file that contains the function body for Foo.
Edit: Its worth noting that this will only cause a link time error.
Edit2: And I ran a quick test and it seems you can't extern to an anonymous namespace.
Edit3:
Something like this would seem sensible (and lose the namespace)
static void Bar()
{
}
void Foo()
{
Bar();
}
You can now "extern void Foo();" but if you try the same with Bar then the linker will fail as Bar no longer has external linkage.