Strange compiler error when trying to construct std::thread: - c++

The following program fails to compile with g++ -std=c++11 -Wall -Werror test.cpp -o test.o:
#include <thread>
using namespace std;
void fill(int n) {
return;
}
int main() {
thread test(fill, 5);
}
test.cpp:9:12: error: no matching constructor for initialization of 'std::__1::thread'
thread test(fill, 5);
^ ~~~~~~~
Is it because fill is conflicting with std::fill from #include <algorithm>? I haven't included this but I suppose <thread> might've.
Changing my function name to fillie (or anything else pretty much) allows it to compile correctly without linking pthread.
I ask because it is a strange compiler error message, and also it means that the thread constructor can't disambiguate which function I am using based on the parameters (which sort of makes sense, but wanted confirmation).

Yes, the problem is because it is not known whether fill is std::fill or your global fill function.
One way to fix it is to write ::fill to explicitly use the global one.

Related

How can I implement a fallback function when some function is missing(at compile time)?

My goal is:
if pthread_setname_np is defined in glibc, we will use glibc's version.
otherwise, we will use a fallback function pthread_setname_np which actually do nothing to prevent compile errors.
This need to be done at compile time.
So I write the following codes
#include <cstdio>
#include <pthread.h>
__attribute__((weak)) int pthread_setname_np(pthread_t thread, const char *name) { printf("foo\n"); return 0; }
int main() {
pthread_setname_np(pthread_self(), "bar");
}
IMO, if I run g++ test_free_bsd.cpp -o test_free_bsd -lpthread, since the symbol is already defined in pthread, so the compile will not link my self-defined symbol.
However, the program still prints out "foo", which means it actually uses my weak symbol.
Then it occurred to me that my self-defined pthread_setname_np is in the same unit with main, there are no linking. So I changed to the following
// g++ test_free_bsd.cpp test_free_bsd2.cpp -o test_free_bsd -lpthread
// test_free_bsd.cpp
#include <cstdio>
#include <pthread.h>
int main() {
pthread_setname_np(pthread_self(), "bar");
}
// test_free_bsd2.cpp
#include <cstdio>
#include <pthread.h>
__attribute__((weak)) int pthread_setname_np(pthread_t thread, const char *name) { printf("foo\n"); return 0; }
However, the program still prints out foo. So I am lost here. IMO, in test_free_bsd.cpp, it will link pthread_setname_np in glibc, rather than in test_free_bsd2.cpp which is a weak symbol.
=== UPDATE ===
Why I wan to do this? There is a fallback in codes of Clickhouse. I am using these codes in my project, though I don't know why they are here. However, I don't want to change its behavior. I only want these lines to take effects only we are sure the glibc we linked to do not has pthread_setname_np.
On FreeBSD pthread_setname_np seems to exists, it is defined in pthread_setname_np.h. I don't know why you get a linker error (I can't test it.)
However, you should be able to use #ifndef _GNU_SOURCE around your pthread_setname_np to only define it if it isn't defined by pthread.h.

Code compiles in Eclipse but not with g++ on Linux

#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
int main ()
{
struct process
{
int burst;
int ar;
};
vector<process> a;
// insert two processes
a.push_back({21, 42});
a.push_back({10, 20});
queue <process> names;
names.push(a[1]);
names.push(a[2]);
cout<<names.front().ar;
return 0;
}
The above code is working fine in eclipse but when i compile it on linux it give many errors. invalid argument and many more. i'm executing it with command:
g++ -o file_name file_name.cpp
does anyone know the reason behind these errors? any solution?
You need to move the definition of struct process out of the main function:
struct process
{
int burst;
int ar;
};
int main ()
{
...
}
Additionally, since you use initializer lists you must enable C++11 suport in GCC:
g++ -std=c++11 -o file_name file_name.cpp
You can not define a struct within a function. In your case, the struct process is defined within the main function.
Also, you need to declare the type of struct you wish to append to the vector.
the '{21, 42}' does not declare a 'process' type (Unless you use C++11).
Using local classes as template arguments and passing braced-init-list to functions are only possible as of C++11. Pass -std=c++11 or -std=c++14 option to g++ and all the errors will disappear. Note that all the letters in the option are in lower case.

Sanity of Headers

I'm just starting to teach C++, coming from some other languages. I am wishing there were some way to consistently check the API created by a (student) file.
Suppose a student submits this file:
// this is stu.cpp
#include <iostream>
using namespace std;
double x(int y) {return y+0.5;}
Actually, suppose I asked the student to define some other function int x(int). I would like to be able to check this by running this code:
// this is stu.h
int x(int);
// this is gra.cpp
#include "stu.h"
#include <iostream>
using namespace std;
int main() {
cout << x(0); // test their code
}
So I am trying to see if the student's implementation matched the required interface, and testing it on input 0. I would have hoped this would not compile. But when I do
g++ -Wall -Wconversion *.cpp -o gra
./gra
It compiles and runs without crashing, giving output 0. This remains true even if I compile the two files separately and link them after.
I know that nm doesn't list return types. Is that the same reason that we can link together two files when the return values don't match? Is there any sane way to test this? (Like are there compile-time typeof assertions?)
Or is this a specific bug because of int and double being interconvertible? Are there additionall compiler options that could catch this?
Instead of compiling the student's code separately, why don't you just include it directly in your tester program?
int x(int);
#include <stu.cpp>
Then you should get a nice error like this:
a.cpp:2:8: error: functions that differ only in their return type cannot be overloaded
While this is not the "normal" way to compile a student's code, it guarantees that the code can be checked.
Alternatively, you may use a compiler command-line option like -include (GCC, Clang) to force the compiler to include a header file containing your desired API when compiling the student's C++ file. As an example:
api.h
int x(int);
compile with g++ stu.cpp -include api.h, and the appropriate error will be raised.
You can do the following:
// this is gra.cpp
#include "stu.h"
#include "stu.cpp"
#include <iostream>
using namespace std;
int main() {
cout << x(0); // test their code
}
And compile only gra.cpp of course.

C++ error: 'unordered_map' does not name a type

I am doing everything correctly as far as I can tell and I have gotten the error message:
error: 'unordered_map' does not name a type
error: 'mymap' does not name a type
In my code, I have:
#include <unordered_map>
using namespace std;
//global variable
unordered_map<string,int> mymap;
mymap.reserve(7000);
void main {
return;
}
I don't see what can be missing here....
EDIT: when I update my declaration to
std::tr1::unordered_map<string,int> mymap;
I an able to eliminate the first error, but when I try to reserve, I still get the second error message.
EDIT2: As pointed out below, reserve must go into main and I need to compile with flag
-std=c++0x
However, there still appear to be errors related to unordered_map, namely:
error: 'class std::tr1::unordered_map<std::basic_string<char>, int>' has no member named 'reserve'
Compile with g++ -std=c++11 (my gcc version is gcc 4.7.2) AND
#include <unordered_map>
#include <string>
using namespace std;
//global variable
unordered_map<string,int> mymap;
int main() {
mymap.reserve(7000); // <-- try putting it here
return 0;
}
If you want to support <unordered_map> for versions older than c++11 use
#include<tr1/unordered_map> and declare your maps in the form :- std::tr1::unordered_map<type1, type2> mymap
which will use the technical report 1 extension for backward compatibility.
You can't execute arbitrary expressions at global scope, so you should put
mymap.reserve(7000);
inside main.
This is also true for other STL containers like map and vector.

c++ mingw STL installation

I recently installed MinGW and MSYS on my Windows 32 machine and it seems to be running fine.
On the C++ compiler, I am including a vector container and getting no errors to that. But I`m getting compile-time errors when I try to use it.
So, the code
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
main() {
// vector<int> A;
printf("\nHeya ..");
}
is running just fine. However, the moment I un-comment line 8-- the vector declaration line, I get the following error (shortened) in compile time:
undefined reference to 'operator delete(void*)'
undefined reference to '__gxx_personality_v0'
You're probably compiling with gcc instead of g++. The actual compiler is the same, but g++ tells the linker to use the default C++ libraries, were gcc only tells it to look at the C libraries. As soon as you use and C++-specific parts of the standard library, gcc will fail.
As an aside, C++ doesn't support the default int rule from old C, so you should really specify the return type from main.
I don't see how you are compiling your code. Your main method is invalid, incorrect signature and you aren't returning anything.
Should be like this:
#include <vector> // include vector.h
#include <stdio.h> // include stdio.h
using namespace std;
int main(int, char**) {
// vector<int> A;
printf("\nHeya ..");
return 0;
}
Also you need to compile this with g++ and not gcc.