C++ Wunused-variable with std::uniqe_ptr [duplicate] - c++

I have a little piece of code in C++:
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main() {
int i=0;
istream_iterator<string> EOS;
double x;
return 0;
}
Now i compile it with my g++ (GCC) 4.4.4
g++ -W -Wall -pedantic test.cc -o test
And get:
test.cc: In function 'int main()':
test.cc:9: warning: unused variable 'i'
test.cc:11: warning: unused variable 'x'
Why there is no warning for unused EOS?

It is not a primitive value, so its constructor and/or destructor might have desired side effects.
To illustrate that this happens in practice: I use a class to time sections of code, that looks roughly like this:
class Timed {
double start;
public:
Timed() { start = now(); }
~Timed() { std::cout << (now() - start) << '\n'; }
}
So to measure how long a function takes, I simply do:
void slow() {
Timed t;
// heavy operation here...
}
The variable t never gets used, but it's still important to the behaviour of the code.

istream_iterator<string> has a constructor, so the declaration of EOS isn't really a no-op like the declarations of i and x are.
Often you want to declare a class-type object and then not do anything with it. For example, consider std::lock_guard in C++0x (boost::scoped_lock in Boost) or any other kind of scope guard class. You don't usually want to do anything with that kind of object, you just want to create the object so that its destructor get run at the end of the block to perform whatever cleanup needs to be performed.

Because you could have done that with a purpose. It's not a primitive. Maybe the constructor and destructor do something important?
MFC even had classes that operated that way, you could do this:
void foo()
{
CWaitCursor cursor;
[...]
}
That would display an hourglass icon for the duration of the function.

Related

Registering file handlers in code running prior to main()

I'm looking into ways to prevent unnecessary clutter in setup code in main() as well as various other places. I often have tons of setup code that registers itself with some factory. A standard example is e.g. handlers for various file types.
To avoid having to write this code and instead just make handlers magically work if linked into the application, I figured I could replace the code by something like the following:
test.cc:
int main() {
return 0;
}
loader.h:
#ifndef LOADER_H_
#define LOADER_H_
#include <functional>
namespace loader {
class Loader {
public:
Loader(std::function<void()> f);
};
} // namespace loader
#define REGISTER_HANDLER(name, f) \
namespace { \
::loader::Loader _macro_internal_ ## name(f); \
}
#endif // LOADER_H_
loader.cc:
#include "loader.h"
#include <iostream>
namespace loader {
Loader::Loader(std::function<void()> f) { f(); }
} // namespace loader
a.cc:
#include <iostream>
#include "loader.h"
REGISTER_HANDLER(a, []() {
std::cout << "hello from a" << std::endl;
})
The idea here is that a.cc would in a real application e.g. call some method where it registers it self as a handler for a certain file type. Compiling the code with c++ -std=c++11 test.cc loader.cc a.cc creates a binary that prints "hello from a" while c++ -std=c++11 test.cc loader.cc stays silent.
I'm wondering if there's something subtle that I might need to be careful with? For example, if someone creates complex objects in the lambda that is run here, I assume weird things can happen during cleanup for example in a multithreaded application?
You wrote:
... unnecessary clutter in setup code in main() ...
int main() {
return 0;
}
This is not preventing unnecessary clutter. This is hiding your initializations. They still occur, but now you have to chase after them. That's really not the way to do it. Also, it will force the use of a lot of global state - in many independent global variables, most probably - which is also a bad thing. Instead, consider writing something like:
class my_app_state { /* ... */ };
my_app_state initialize(/* perhaps with argc and argv here? */) {
//
// Your "unnecessary" clutter goes here...
//
return whatever;
}
int main() {
auto app_state = initialize();
//
// do stuff involving the app_state...
//
}
and don't try to "game" the program loader.
This approach is not guaranteed to work:
[basic.start.dynamic]/4 It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized.
Thus, the initialization of _macro_internal_a may be deferred until something in a.cc is used. And since nothing in a.cc is in fact used, the initialization may not be performed at all.
In practice, linkers tend to discard object files that do not appear to be referenced by anything in the program (especially when those files come from libraries).

G++ not removing static class instance [duplicate]

I have a little piece of code in C++:
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main() {
int i=0;
istream_iterator<string> EOS;
double x;
return 0;
}
Now i compile it with my g++ (GCC) 4.4.4
g++ -W -Wall -pedantic test.cc -o test
And get:
test.cc: In function 'int main()':
test.cc:9: warning: unused variable 'i'
test.cc:11: warning: unused variable 'x'
Why there is no warning for unused EOS?
It is not a primitive value, so its constructor and/or destructor might have desired side effects.
To illustrate that this happens in practice: I use a class to time sections of code, that looks roughly like this:
class Timed {
double start;
public:
Timed() { start = now(); }
~Timed() { std::cout << (now() - start) << '\n'; }
}
So to measure how long a function takes, I simply do:
void slow() {
Timed t;
// heavy operation here...
}
The variable t never gets used, but it's still important to the behaviour of the code.
istream_iterator<string> has a constructor, so the declaration of EOS isn't really a no-op like the declarations of i and x are.
Often you want to declare a class-type object and then not do anything with it. For example, consider std::lock_guard in C++0x (boost::scoped_lock in Boost) or any other kind of scope guard class. You don't usually want to do anything with that kind of object, you just want to create the object so that its destructor get run at the end of the block to perform whatever cleanup needs to be performed.
Because you could have done that with a purpose. It's not a primitive. Maybe the constructor and destructor do something important?
MFC even had classes that operated that way, you could do this:
void foo()
{
CWaitCursor cursor;
[...]
}
That would display an hourglass icon for the duration of the function.

C++ - Initialiser list for unordered_map of class method function pointers

I'm new to C++11 so I have been experimenting with std::function today and I'm trying to use it to create a hash table for strings to class function pointers for a small assembler I am creating:
assemble.cpp
#include <iostream>
#include <unordered_map>
#include <functional>
#include <vector>
#include <string>
class Assembler {
public:
// Assembles the source file and writes it
bool assemble(std::string output_file);
// Creates the symbol table from a (.s) file
bool create_symbol_table(std::string file_name);
private:
// Hash table for opcode to functions
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add",assemble_data_processing}
};
bool assemble_data_processing(std::vector<std::string> instruction);
};
bool Assembler::assemble_data_processing(std::vector<std::string> instruction) {
std::cout << "Data Processing" << std::endl;
return false;
}
This gives me a compile time error with g++:
g++ -Wall -g -Werror -std=c++11 -o assemble.o assemble.cpp
assemble.cpp:28:5: error: could not convert ‘{{"add", ((Assembler*)this)->Assembler::assemble_data_processing}}’ from ‘<brace-enclosed initializer list>’ to ‘std::unordered_map<std::__cxx11::basic_string<char>, std::function<bool(std::vector<std::__cxx11::basic_string<char> >)> >’
};
^
But if make the function a non-class function then it compiles without problems:
bool assemble_data_processing(std::vector<std::string> instruction) {
std::cout << "Data Processing" << std::endl;
return false;
}
How can I initialise the unordered_map in a brace initialiser list for class methods?
You can use std::bind
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add", std::bind(&Assembler::assemble_data_processing, this, std::placeholders::_1}
};
Or a lambda
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add", [this](std::vector<std::string> instruction){return assemble_data_processing(instruction);}}
};
Or make your function static.
A std::function cannot hold non-bound member functions.
You have three ways to fix this depending on the circumstance.
a) If assemble_data_processing does not use any member data, make it a static member function, and call it a day.
b) If your cache is associated with a single Assembler instance, then bind the function using std::bind, using something similar to:
opcode_map =
{
{"add",std::bind(&Assembler::assemble_data_processing, this, _1)}
};
c) if the Assembler instance is something that gets determined later, then you will have to ditch std::function, and use a good-old function pointer to member function.

Using a variable from a different file before main

I'm having a little trouble understanding why my code works the way it does (or doesn't work the way it ought to).
I'm trying to write (in C++) an interface that allows to use some functions operating on unordered_map from the standard template library in C. However, I'd also like to write a namespace that allows to use them in C++ as well.
What I'm asking is not how this can be thone in a different way, but why it works the way it does;
Let's say for a while that I need only two functions: to add elements and write the size of the map. The header is the following:
//project.h
#ifdef __cplusplus
extern "C" {
#endif
void add(int, int);
void give_size();
#ifdef __cplusplus
}
#endif
The source code:
//project.cc
#include <unordered_map>
#include <iostream>
#include "project.h"
using namespace std;
unordered_map<int, int> my_map;
void add(int arg, int val) {
my_map.insert ({{arg, val}});
}
void give_size() {
cout << my_map.size() << endl;
}
The interface for C++:
//cproject
namespace pro {
#include "project.h"
}
and a test:
//test.cc
#include "cproject"
namespace {
unsigned long test() {
::pro::add(1,2);
::pro::add(3,4);
return 0;
}
unsigned long dummy = test();
}
int main() {
::pro::give_size();
return 0;
}
And, for completeness, the Makefile:
g++ -Wall -std=c++11 -c -o project.o project.cc
g++ -Wall -std=c++11 -c -o test.o test.cc
g++ test.o project.o -o test
The problem is, of course, that running test outputs 0 instead of 2 - which means that the map disappears somewhere before the test's main.
I was thinking it might be some sort of static initialization order fiasco, however I don't find the attached solution very helpful, since I don't explicitly call objects from the project.cc file in test.cc.
I would appreciate any help with that issue.
Yes, it's the poorly named static initialization order fiasco. Poorly named because the C++ standard calls it "dynamic initialization"; "static initialization" is something different.
which means that the map disappears somewhere before the test's main
Not quite. The problem is that you use the map before it's there, adding values to it. Now it happens that for some map implementations, a zero-initialized state (and that is what is done to all global variables before any dynamic initializers run) is the same as what the default constructor does. So the code in test is executed first and tries to add things to the map, and the map's insert function works just fine, creating nodes, setting internal pointers to the nodes, etc.
Then the actual default constructor of the map runs, resetting those pointers to null, leaking and forgetting all the nodes you created. Your previous insertions are undone, and the map is empty again.
The solutions provided in your link would work; you implicitly call objects through the free functions, even if you don't do it explicitly. There's no real distinction. You still replace the global my_map in project.cc with a function that returns a reference to a function-level static (or pointer, depending on which exact solution you choose). The only difference is that you call this function not from within test.cc, but from within add and give_size.
As a side note, this whole global state thing is generally rather suspect. It's not thread-safe, and it makes it harder to understand what the program is doing. Consider not doing it this way at all.

g++ does not show a 'unused' warning

I have a little piece of code in C++:
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main() {
int i=0;
istream_iterator<string> EOS;
double x;
return 0;
}
Now i compile it with my g++ (GCC) 4.4.4
g++ -W -Wall -pedantic test.cc -o test
And get:
test.cc: In function 'int main()':
test.cc:9: warning: unused variable 'i'
test.cc:11: warning: unused variable 'x'
Why there is no warning for unused EOS?
It is not a primitive value, so its constructor and/or destructor might have desired side effects.
To illustrate that this happens in practice: I use a class to time sections of code, that looks roughly like this:
class Timed {
double start;
public:
Timed() { start = now(); }
~Timed() { std::cout << (now() - start) << '\n'; }
}
So to measure how long a function takes, I simply do:
void slow() {
Timed t;
// heavy operation here...
}
The variable t never gets used, but it's still important to the behaviour of the code.
istream_iterator<string> has a constructor, so the declaration of EOS isn't really a no-op like the declarations of i and x are.
Often you want to declare a class-type object and then not do anything with it. For example, consider std::lock_guard in C++0x (boost::scoped_lock in Boost) or any other kind of scope guard class. You don't usually want to do anything with that kind of object, you just want to create the object so that its destructor get run at the end of the block to perform whatever cleanup needs to be performed.
Because you could have done that with a purpose. It's not a primitive. Maybe the constructor and destructor do something important?
MFC even had classes that operated that way, you could do this:
void foo()
{
CWaitCursor cursor;
[...]
}
That would display an hourglass icon for the duration of the function.