What I know about C++ is that the order of the constructions (and destructions) of global instances should not be assumed.
While I'm writing code with a global instance which uses std::cout in the constructor & destructor, I got a question.
std::cout is also a global instance of iostream. Is std::cout guaranteed to be initialized before any other global instances?
I wrote a simple test code and it works perfectly, but still I don't know why.
#include <iostream>
struct test
{
test() { std::cout << "test::ctor" << std::endl; }
~test() { std::cout << "test::dtor" << std::endl; }
};
test t;
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
It prints
test::ctor
Hello world
test::dtor
Is there any possibility that the code doesn't run as expected?
The answer differs depending on if you're using C++03 or C++11.
In C++11, your code is guaranteed to work, but in C++03 it's unspecified; your only guarantee is that by the time main() is entered, the standard streams had been initialized. (That said, all mainstream implementations initialize them prior to running any dynamic initialization, making them fine to use.)
You can force initialization by constructing an std::ios_base::Init object, like so:
#include <iostream>
struct test
{
test() { std::cout << "test::ctor" << std::endl; }
~test() { std::cout << "test::dtor" << std::endl; }
private:
std::ios_base::Init mInitializer;
};
test t;
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
Now when test constructs, it initializes mInitializer and guarantees the streams are ready to use.
C++11 fixed this slightly annoying behavior by acting as if every instance of #include <iostream> were followed by static std::ios_base::Init __unspecified_name__;. This automatically guarantees the streams are ready to use.
According to §27.3/2:
The objects [std::cin, std::cout, etc.] are constructed, and the
associations are established at some time prior to or during first
time an object of class ios_base::Init is constructed, and in any case
before the body of main begins execution.
Your question is about the order of construction of static objects. I believe that the language specification leaves it undefined.
GCC has the init_priority attribute to play with the order.
And I believe you should not worry that much in practice.
Related
Little known feature of C++ is ref-qualifiers for member functions.
It works as I expect it to work in most cases, but it seems that std::optional does not forward the knowledge of its imminent demise to contained object member functions.
For example consider the following code:
#include <chrono>
#include <iostream>
#include <optional>
struct Noisy {
Noisy(const std::string& data): data_(data){
}
~Noisy(){
std::cout << "Goodbye" << std::endl;
}
std::string data_;
const std::string& data() const & {
std::cout << "returning data by ref" << std::endl;
return data_;
}
std::string data() && {
std::cout << "returning data by move" << std::endl;
return std::move(data_);
}
};
int main() {
for (const auto chr: Noisy{"Heeeeeeeeeeeeeeeeello wooooorld"}.data()){
std::cout << chr;
}
std::cout << std::endl;
for (const auto chr: std::optional<Noisy>{"Heeeeeeeeeeeeeeeeello wooooorld"}->data()){
std::cout << chr;
}
std::cout << std::endl;
}
output is:
returning data by move
Goodbye
Heeeeeeeeeeeeeeeeello wooooorld
returning data by ref
Goodbye
(crash in clang with sanitizer or garbage(UB))
I was hoping that temporary std::optional will be kind enough to call correct (data() &&) function, but it seems it does not happen.
Is this a language limitation, or std::optional just does not have correct machinery for this?
Full godbolt link.
note: my motivation is hacking around to see if I can be clever to enable safer usage of my classes in range based for loop, but realistically it is not worth the effort, this question is mostly about learning about language.
Overloaded operator arrow cannot do what you want; it terminates with a pointer always.
x->y is defined by the standard as (*x).y if and only if x is a pointer; otherwise it is (x.operator->())->y. This recursion only terminates if you hit a pointer.1
And there is no pointer to temporary type. Try this:
const auto chr: (*std::optional<Noisy>{"Heeeeeeeeeeeeeeeeello wooooorld"}).data()
Which does call the rvalue method. (via #largest_prime).
1 This recursion can also do Turing complete computation.
What I know about C++ is that the order of the constructions (and destructions) of global instances should not be assumed.
While I'm writing code with a global instance which uses std::cout in the constructor & destructor, I got a question.
std::cout is also a global instance of iostream. Is std::cout guaranteed to be initialized before any other global instances?
I wrote a simple test code and it works perfectly, but still I don't know why.
#include <iostream>
struct test
{
test() { std::cout << "test::ctor" << std::endl; }
~test() { std::cout << "test::dtor" << std::endl; }
};
test t;
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
It prints
test::ctor
Hello world
test::dtor
Is there any possibility that the code doesn't run as expected?
The answer differs depending on if you're using C++03 or C++11.
In C++11, your code is guaranteed to work, but in C++03 it's unspecified; your only guarantee is that by the time main() is entered, the standard streams had been initialized. (That said, all mainstream implementations initialize them prior to running any dynamic initialization, making them fine to use.)
You can force initialization by constructing an std::ios_base::Init object, like so:
#include <iostream>
struct test
{
test() { std::cout << "test::ctor" << std::endl; }
~test() { std::cout << "test::dtor" << std::endl; }
private:
std::ios_base::Init mInitializer;
};
test t;
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
Now when test constructs, it initializes mInitializer and guarantees the streams are ready to use.
C++11 fixed this slightly annoying behavior by acting as if every instance of #include <iostream> were followed by static std::ios_base::Init __unspecified_name__;. This automatically guarantees the streams are ready to use.
According to §27.3/2:
The objects [std::cin, std::cout, etc.] are constructed, and the
associations are established at some time prior to or during first
time an object of class ios_base::Init is constructed, and in any case
before the body of main begins execution.
Your question is about the order of construction of static objects. I believe that the language specification leaves it undefined.
GCC has the init_priority attribute to play with the order.
And I believe you should not worry that much in practice.
During some coding this morning I managed to enter and compile something akin to the following.
void a_function(void)
{
A_Class(std::string);
... //Other code continues
}
(names have been replaced to protect the identity of those classes involved)
What I had intended to have was a named instance A_Class an_instance(a_string); which I know would be in scope until the end of the function. What is the scope and lifetime of the A_Class created in this function?
I expect I could do something clever in the construction phase to make the lifetime almost anything I want. In this case the constructor makes a function call and a printf while the destructor does similar. Nothing invokes new, delete, malloc or anything of that sort.
Since C++98, a temporary lasts until the end of the full-expression, unless its lifetime is extended by binding to a reference.
The rules were different, as I recall, in ARM (the Annotated Reference Manual by Stroustrup and Ellis) C++.
It's not generally possible to figure out the standard's guarantees by just inspecting examples in a debugger or via trace statements, so the question has merit.
Only names have scope, so that concept is irrelevant here.
You're creating a temporary object.
Like all temporary objects, its lifetime lasts until the end of the full-expression where it was created, i.e until the ";" in this case, unless it's bound to a const reference variable.
The expression:
A_Class();
creates a temporary object of class A_Class. The temporary is destroyed after the evaluation of the full expression which lexicaly contains it -- in this case, the temporary will be destroyed immediately after its construction.
In an attempt to answer my own question,
Second Attempt
Updated test code now reads:
#include <iostream>
class Class_A
{
public:
Class_A(std::string a_string)
: saved_string(a_string)
{
std::cout << "Class_A Constructed:" << saved_string << std::endl;
}
~Class_A()
{
std::cout << "Class_A Deconstructed:" << saved_string << std::endl;
}
std::string saved_string;
};
class Class_B
{
public:
Class_B(std::string a_string)
: saved_string(a_string)
{
std::cout << "Class_B Constructed:" << saved_string << std::endl;
}
~Class_B()
{
std::cout << "Class_B Deconstructed:" << saved_string << std::endl;
}
std::string saved_string;
};
int main ()
{
std::cout << "Welcome to the lifetime test." << std::endl;
Class_A a_a("A");
Class_B a_b("B"); //Now I have to have () here too
std::cout << "Now for the interesting bit." << std::endl;
Class_A("a"); //Have to have the ()
Class_B("b");
std::cout << "Fin." << std::endl;
return 0;
}
Which when executed produces:
$ ./a.out
Welcome to the lifetime test.
Class_A Constructed:A
Class_B Constructed:B
Now for the interesting bit.
Class_A Constructed:a
Class_A Deconstructed:a
Class_B Constructed:b
Class_B Deconstructed:b
Fin.
Class_B Deconstructed:B
Class_A Deconstructed:A
So I can now see the lifetimes and I am compelled to use () or rather ("string") in the appropriate places. It is a little odd that a_a() is a function declaration inside a function in the First Attempt but `a_a_("A") is a constructor in the second. I was unaware that it was permitted to declare functions inside the definition of other functions but I suppose it make some sense for a few times when you might have some odd linkage going on in the background.
The lifetime of the unnamed temporary is only as long as the expression it is part of. Up until the ;.
First Attempt
I got as far as:
class Class_A
{
public:
Class_A()
{
std::cout << "Class_A Constructed" << std::endl;
}
~Class_A()
{
std::cout << "Class_A Deconstructed" << std::endl;
}
};
class Class_B
{
public:
Class_B()
{
std::cout << "Class_B Constructed" << std::endl;
}
~Class_B()
{
std::cout << "Class_B Deconstructed" << std::endl;
}
};
int main ()
{
std::cout << "Welcome to the lifetime test." << std::endl;
Class_A a_a();
Class_B a_b;
std::cout << "Now for the interesting bit." << std::endl;
Class_A(); //Have to have the ()
Class_B();
std::cout << "Fin." << std::endl;
return 0;
Which produces:
$ g++ main.cpp
$ ./a.out
Welcome to the lifetime test.
Class_B Constructed
Now for the interesting bit.
Class_A Constructed
Class_A Deconstructed
Class_B Constructed
Class_B Deconstructed
Fin.
Class_B Deconstructed
So I only have 1 Class_A constructed. Which is a little confusing as I would have expected a_a and a_b to have the same lifetimes. Now what have I done.
(update to follow I am sure)
It does seem to show that the calls to a constructor without a variable name only exist for the line/statement they are in (until the ;). This makes some sense when I think about functors, as pointed out by #douglas-o-moen
#include <iostream>
using namespace std;
int gc = 0;
struct A {
int id;
A():id(gc++) { cout << "Constructed #" << id << "\n"; }
A(const A& b):id(gc++) { cout << "Copying from " << b.id << " to " << id << "\n"; }
~A() { cout << "Destructed #" << id << "\n"; }
};
A f() {
A a;
cout << "Exiting f()" << "\n";
return a;
}
int main() {
A b = f();
cout << "Exiting main()" << "\n";
return 0;
}
The output produced (with no optimization (-O0), and using either of these compilers: g++ 4.6.3, g++ 4.8.1, clang++ 3.0 on Ubuntu):
Constructed #0
Exiting f()
Exiting main()
Destructed #0
My guess for copy constructor not being called (despite it having observable side effects), and object a not getting destroyed in f()) is NRVO (similar case as described in: https://stackoverflow.com/a/3906038/1857518).
My questions:
Is the output of this program well specified by C++ standards ?
If (1) is true, then which one of the following case it is:
The output will always exactly be this
There exist a legal & finite set of outputs, say, Out (such that |Out| > 1). And a conformant compiler can produce any one from the set Out. If this is the case, what does the set Out looks like.
What you see in this behavior is called copy elision.
1.Is the output of this program well specified by C++ standards?
Yes the compiler is allowed to optimize the copy side effect away for such case.
2.The output will always exactly be this
No. As mentioned the compiler is allowed to optimize the copying behavior out, but doesn't necessarily need to do it.
Thus, you can't rely on any side effects being in place or removed for returned 'copies'. See also this post: Is it possible to ensure copy elision?
Suppose I have two overloaded functions :
fun1(int)
fun1()
In this case how can I use #pragma startup directive to start my program's execution with fun1(int) ?
The syntax only contains the function name :
#pragma startup fun1 100
Is there any way by which I can make a choice between these two functions?
UPDATE:
compiler- turbo c/c++ 3.1 (sorry for an old compiler )
It is a Borland specific directive, still documented as well. It just lets you specify a function that runs before the main() function is entered. You normally use it for an initialization function. It is a small band-aid for the infamous "static initialization order fiasco" that C and C++ implementations suffer from. Not so sure it stops the bleeding, having to pick the priority number ought to get impractical when the program gets large.
Anyhoo, nothing you ought to use as a replacement of main(). Although I'd suspect you could make it work as long as you don't return from the function and call exit(). You can't use an argument of course, there's nothing meaningful that the CRT can pass. So overloads can't work either. Stick with main().
#joey-rohan, I dont have borland but have tried to provide some code below to demonstrate:
#pragma start requires a non parameterised function, the number after the function call is the priority of the function where 0 is the highest and 255 the lowest. The function should ideally (varies in some compilers) be defined prior to the #pragma call. Source: embarcadero
I have done a bit of scouting about and think that the solution to your dilemma would be to use a mixture of #define and #pragma to achieve what you would like to do. For example something like:
#include <iostream>
#define myvalue 100
#define usemyvalue 0
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma start fun1 10
int main()
{
std::cout << "Hello World\n";
return 0;
}
I know this is not as elegant as I would wish, therefore its probably not as elegant as you would like either, however it does allow for the functionality you need, with minimal modification. Unfortunately i only have GCC available to test against on this machine and it does not seem to support #pragma start it does however support a differing way of achieving the same (as shown on C Language Constructors and Destructors with GCC
so here is some code for GCC which I could test to let you see how to achieve what you are asking (because I would hate to pst a methodology that cannot be proven):
#include <iostream>
#define myvalue 100
#define usemyvalue 1 // this is the control switch to determine which to use,
// if the value is 1 then will pass a variable, otherwise will use
// the fun1(void) function
void fun1 (void) __attribute__((constructor));
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma startup fun1
int main()
{
std::cout << "now running main function.\n";
std::cout << "Hello World\n";
return 0;
}
I suspect that the second method would also work with Borlands compiler but without access to it I cannot swear to that.
Hope this helps!
I can neither find any documentation on your compiler, nor use the compiler itself to check my guess. But from what I remember, #pragma startup takes function without arguments and returning void.
I would further guess that your code is not going to work if you leave only function taking int argument.
Disregarding that, I think it's not possible to pass an argument to function called in such a way.
As a solution I would propose you creating wrapper function, calling whatever function you would like with necessary arguments, like:
void start()
{
#pragma startup start
fun1( global_var_name );
}
I'm not exactly sure I understand the restrictions, but how about simply defining another function with a different name to forward to the function you want?
void fun2() { fun1(42); }
#pragma startup fun2 100