The following is my code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main() {
int cpid=fork();
if(cpid==0) {
printf("%d %d\n",getpid(),getppid());
}
else {
printf("hello");
wait(NULL);
}
}
When I compile this using the following:
g++ -std=c++11 multiple.cpp -o multiple
It gives me the following
multiple.cpp: In function 'int main()':
multiple.cpp:34:23: error: no matching function for call to 'wait::wait(NULL)'
wait(NULL);
^
multiple.cpp:34:23: note: candidates are:
In file included from /usr/include/stdlib.h:42:0,
from multiple.cpp:4:
/usr/include/bits/waitstatus.h:66:7: note: wait::wait()
union wait
/usr/include/bits/waitstatus.h:66:7: note: candidate expects 0 arguments, 1 provided
/usr/include/bits/waitstatus.h:66:7: note: constexpr wait::wait(const wait&)
/usr/include/bits/waitstatus.h:66:7: note: no known conversion for argument 1 from 'int' to 'const wait&'
/usr/include/bits/waitstatus.h:66:7: note: constexpr wait::wait(wait&&)
/usr/include/bits/waitstatus.h:66:7: note: no known conversion for argument 1 from 'int' to 'wait&&'
But if I change the extension to .c and use gcc -o multiple multiple.c it works. Why is this happening?
You have not included the correct header file that the wait() documentation tells you need.
You need
#include <sys/wait.h>
Because wait is declared in sys/wait.h, which you do not include, and C++ requires all the functions to be prototyped before used. C, on the other hand, does not.
You did not include the header for the POSIX wait function, per the documentation:
#include <sys/wait.h>
It is surprising but not inconceivable that the equivalent standard library headers in your C toolchain just so happen to include this themselves, whereas the C++ ones you have used do not.
More likely, you are inadvertently making use of the terrible rule in C that says you can use some functions before they have been declared.
Related
I was working on this thread swap c++ map objects in multithreaded environment
However,
#include <memory>
#include <thread>
#include <chrono>
#include <atomic>
#include <iostream>
using namespace std;
shared_ptr<std::string> the_string;
int main()
{
atomic_store(&the_string, std::make_shared<std::string>("first string"));
}
gives a compile time error
error: no matching function for call to 'atomic_store'
atomic_store(&the_string, std::make_shared<std::string>("first string"));
^~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/atomic:1165:1: note: candidate template ignored: could not match 'atomic' against 'shared_ptr'
atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
I did see a few threads on this problem and understand that it could be related to C++ version I have /usr/include/c++/4.2.1/ and /usr/include/c++/4.8.5/ on another box, both give the same issue. Should I upgrade the C++ version?
I resolved this issue by passing -std=c++11 flag.
I resolved this issue by passing the flag -std=c++11
It compiles fine here with GCC 8.3 and Clang 8.0, so yes, you should upgrade your compiler.
Consider following program:
#include <cstdio>
#include <cmath>
int main()
{
int d = (int)(abs(0.6) + 0.5);
printf("%d", d);
return 0;
}
g++ 7.2.0 Output 0 ( See live demo here )
g++ 6.3.0 ( See live demo here )
prog.cc: In function 'int main()':
prog.cc:6:26: error: 'abs' was not declared in this scope
int d = (int)(abs(0.6) + 0.5);
^
prog.cc:6:26: note: suggested alternative:
In file included from prog.cc:2:0:
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/cmath:103:5: note: 'std::abs'
abs(_Tp __x)
^~~
clang++ 5.0.0 Output 1 ( See live demo here )
clang++ 3.6.0 ( See live demo here )
prog.cc:6:19: error: use of undeclared identifier 'abs'; did you mean 'fabs'?
int d = (int)(abs(0.6) + 0.5);
^~~
fabs
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:181:14: note: 'fabs' declared here
__MATHCALLX (fabs,, (_Mdouble_ __x), (__const__));
^
/usr/include/math.h:71:26: note: expanded from macro '__MATHCALLX'
__MATHDECLX (_Mdouble_,function,suffix, args, attrib)
^
/usr/include/math.h:73:22: note: expanded from macro '__MATHDECLX'
__MATHDECL_1(type, function,suffix, args) __attribute__ (attrib); \
^
/usr/include/math.h:76:31: note: expanded from macro '__MATHDECL_1'
extern type __MATH_PRECNAME(function,suffix) args __THROW
^
/usr/include/math.h:79:42: note: expanded from macro '__MATH_PRECNAME'
#define __MATH_PRECNAME(name,r) __CONCAT(name,r)
^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:88:23: note: expanded from macro '__CONCAT'
#define __CONCAT(x,y) x ## y
^
1 error generated.
Microsoft VC++ 19.00.23506 Output 1 ( See live demo here )
What exactly is happening here in this program ? Why it gives different output when compiled on different C++ compilers ? Why program exhibits different behavior even on different version of same compiler ? Is this compiler issue or standard library (libstdc++ & libc++) issue ? What C++ standard says about this ?
P.S: I know that I need to write std::abs instead of abs. But this is not my question.
All the cname library headers that bring in functionality from the C standard library must introduce those symbols in namespace std. They also may, but definitely not must introduce them into the global namesapce. [headers]/4:
Except as noted in Clauses [library] through [thread] and Annex
[depr], the contents of each header cname is the same as that of the
corresponding header name.h as specified in the C standard library. In
the C++ standard library, however, the declarations (except for names
which are defined as macros in C) are within namespace scope of the
namespace std. It is unspecified whether these names (including any
overloads added in Clauses [language.support] through [thread] and
Annex [depr]) are first declared within the global namespace scope and
are then injected into namespace std by explicit using-declarations.
So different compilers, and even different compiler versions, mean different implementation details.
Consider the following (buggy) C++ code:
#include <cmath>
#include <cstdlib>
#include <iostream>
int main() {
if (abs(-0.75) != 0.75) {
std::cout << "Math is broken!\n";
return 1;
} else {
return 0;
}
}
This code is buggy because it calls abs (meaning ::abs) instead of std::abs. Depending on the implementation, ::abs might not exist, or it might be the C abs, or it might be an overload set including a version for double, like std::abs is.
With Clang on Linux, at least in my environment, it turns out to be the second option: C abs. This provokes two warnings, even without explicitly enabling any:
<source>:7:9: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
if (abs(-0.75) != 0.75) {
^
<source>:7:9: note: use function 'std::abs' instead
if (abs(-0.75) != 0.75) {
^~~
std::abs
<source>:7:13: warning: implicit conversion from 'double' to 'int' changes value from -0.75 to 0 [-Wliteral-conversion]
if (abs(-0.75) != 0.75) {
~~~ ^~~~~
On GCC, I get different results in different environments and I haven’t yet figured out what details of the environment are relevant. The more common option, though, is also that it calls the C abs function. However, even with -Wall -Wextra -pedantic, it gives no warnings. I can force a warning with -Wfloat-conversion, but that gives too many false positives on the rest of my codebase (which perhaps I should fix, but that’s a different issue):
<source>: In function 'int main()':
<source>:7:18: warning: conversion to 'int' alters 'double' constant value [-Wfloat-conversion]
if (abs(-0.75) != 0.75) {
^
Is there a way to get a warning whenever I use a library function through the global namespace, when the version in namespace std is an overload?
Here's a solution. I'm not happy with it, but it might work for you:
namespace DontUseGlobalNameSpace {
// put all std functions here you want to catch
int abs(int x);
}
using namespace DontUseGlobalNameSpace;
Now, if you use abs() without qualification, you'll get a "symbol is ambiguous" error.
This is going to be difficult. The GCC <cmath> header simply includes <math.h>, #undefs its macros (just in case) and defines the C++ functions as inline functions which make some use of identifiers from <math.h>. Most of the functions in fact refer to compiler builtins: for instance, std::abs is defined using __builtin_abs and not ::abs.
Since <cmath> and your "buggy program" are all in the same translation unit, it's hard to see how the visibility could be separated: how the inline functions in <cmath> could be allowed to use <math.h> stuff, while your code wouldn't.
Well, there is the following way: <cmath> would have to be rewritten to provide its own locally scoped declarations for anything that it needs from <math.h> and not actually include that header.
What we can do instead is prepare a header file which re-declares the functions we don't want, with an __attribute__ ((deprecated)):
// put the following and lots of others like it in a header:
extern "C" int abs(int) throw () __attribute__ ((deprecated));
#include <cmath>
#include <cstdlib>
#include <iostream>
int main() {
if (abs(-0.75) != 0.75) {
std::cout << "Math is broken!\n";
return 1;
} else {
return 0;
}
}
Now:
$ g++ -Wall buggy.cc
buggy.cc: In function ‘int main()’:
buggy.cc:9:7: warning: ‘int abs(int)’ is deprecated [-Wdeprecated-declarations]
if (abs(-0.75) != 0.75) {
^~~
In file included from /usr/include/c++/6/cstdlib:75:0,
from buggy.cc:4:
/usr/include/stdlib.h:735:12: note: declared here
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
^~~
buggy.cc:9:16: warning: ‘int abs(int)’ is deprecated [-Wdeprecated-declarations]
if (abs(-0.75) != 0.75) {
^
In file included from /usr/include/c++/6/cstdlib:75:0,
from buggy.cc:4:
/usr/include/stdlib.h:735:12: note: declared here
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
^~~
A linker warning would be simpler. I tried that; the problem is that this test program doesn't actually generate an external reference to abs (even though there is an #undef abs in <cmath>). The call is being inlined, and so evades the linker warning.
Update:
Following up DanielH's comment, I have come up with a refinement of the trick which allows std::abs but blocks abs:
#include <cmath>
#include <cstdlib>
#include <iostream>
namespace proj {
// shadowing declaration
int abs(int) __attribute__ ((deprecated));
int fun() {
if (abs(-0.75) != 0.75) {
std::cout << "Math is broken!\n";
return 1;
} else {
return std::abs(-1); // must be allowed
}
}
}
int main() {
return proj::fun();
}
Simple namespaces can be used. Also, we don't need the deprecated attribute; we can just declare abs as an incompatible function, or a non-function identifier entirely:
#include <cmath>
#include <cstdlib>
#include <iostream>
namespace proj {
// shadowing declaration
class abs;
int fun() {
if (abs(-0.75) != 0.75) {
std::cout << "Math is broken!\n";
return 1;
} else {
return std::abs(-1); // must be allowed
}
}
}
int main() {
return proj::fun();
}
$ g++ -std=c++98 -Wall buggy.cc -o buggy
buggy.cc: In function ‘int proj::fun()’:
buggy.cc:10:18: error: invalid use of incomplete type ‘class proj::abs’
if (abs(-0.75) != 0.75) {
^
buggy.cc:7:9: note: forward declaration of ‘class proj::abs’
class abs;
^~~
buggy.cc:16:3: warning: control reaches end of non-void function [-Wreturn-type]
}
^
With this approach, we just need a list of names and dump them into some header that provides this:
int abs, fabs, ...; // shadow all of these as non-functions
I used -stdc++98 in the g++ command line to emphasizes that this is just old school C++ namespace semantics at work.
This code will let you detect whether the trap exists in a particular environment:
double (*)(double) = &::abs; // fails if you haven't included math.h, possibly via cmath
But it won't help you spot the places you fall into the trap.
I have a simple program containing the following code:
namespace nam
{
struct S{};
void f(S *){}
}
void f(nam::S *){}
int main()
{
nam::f(nullptr);
nam::S s;
f(&s);
return 0;
}
I expect that this will compile fine because I am calling f the second time without specifying namespace nam. However, upon compiling the code, I get this error:
$ g++ main.cpp -std=c++11 -Wall -Wextra
main.cpp: In function ‘int main()’:
main.cpp:14:9: error: call of overloaded ‘f(nam::S*)’ is ambiguous
f(&s);
^
main.cpp:7:6: note: candidate: void f(nam::S*)
void f(nam::S *){}
^
main.cpp:4:10: note: candidate: void nam::f(nam::S*)
void f(S *){}
Compiler and version:
$ gcc --version
gcc (Debian 5.3.1-14) 5.3.1 20160409
After trying this with different compilers, similar errors are returned. This seems to be a defined part of C++. I can't find anywhere on the internet where it says that calling a function with a struct in namespace nam as a parameter effectively implies using namespace nam; and requires ::f to remove ambiguity. I have 2 questions about this:
Where is this defined in the C++ standard?
Is there a good reason for this behavior?
Personally I like to avoid using namespace x; and similar. I want the compiler to give me an error when I don't specify a namespace. This behavior stops the compiler from doing so, and this means my code is inconsistent in places, because I occasionally forget to specify the namespace when calling functions like f that are not declared globally anywhere.
Your implementation of f(nam::S*) is outside of the namespace of 'nam'
change:
void f(nam::S *){}
to:
void nam::f(nam::S *){}
(or just move the enclosing namespace bracket) and all should be fine.
if your call to f(&s) in the current namespace was intentional then you need to specify this by changing the function call to
::f(&s)
As was said in the comments, this is due to argument-dependent lookup. I guess now I'll have to figure out now if I want to always specify the namespace in my code where this would make it unnecessary, or never specify it.
I am not familiar with templates. I've just started learning it. Why I am getting errors in following program?
#include <iostream>
#include <string>
using std::cout;
using std::string;
template<class C>
C min(C a,C b) {
return a<b?a:b;
}
int main()
{
string a="first string";
string b="second string";
cout<<"minimum string is: "<<min(a,b)<<'\n';
int c=3,d=5;
cout<<"minimum number is: "<<min(c,d)<<'\n';
double e{3.3},f{6.6};
cout<<"minimum number is: "<<min(e,f)<<'\n';
char g{'a'},h{'b'};
cout<<"minimum number is: "<<min(g,h)<<'\n';
return 0;
}
Errors:
13 [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous
6 [Note] C min(C, C) [with C = std::basic_string<char>]
Please help me.
There are a two things going on here.
Your first problem is that you only included part of the error message. Here is a link to the code being complied in gcc and clang, and one of the resulting error messages (in full):
main.cpp:13:34: error: call to 'min' is ambiguous
cout<<"minimum string is: "<<min(a,b)<<'\n';
^~~
/usr/include/c++/v1/algorithm:2579:1: note: candidate function [with _Tp = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
min(const _Tp& __a, const _Tp& __b)
^
main.cpp:6:3: note: candidate function [with C = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
C min(C a,C b) {
^
there are two candidates. One at main.cpp:6:3 (line 6, character 3) and one at algorithm:2579:1 (line 2579, character 1).
One of them you wrote, and one of them in #include <algorithm>.
One of your header files included <algorithm> without you asking for it. The standard headers are allowed to do this, as annoying as it is sometimes.
In <algorithm> there is a std::min function template. As std::string is an instance of a template class in namespace std, the function template std::min is found via a process called "argument dependent lookup" or "Koenig lookup". (function overload candidates are searched for locally, and also in the namespaces of the arguments to the function, and in the namespaces of the template arguments to the arguments to the function, and in the namespaces of the things pointed to by the arguments of the function, etc.)
Your local function min is also found, as it is in the same namespace as the body of main.
Both are equally good matches, and the compiler cannot decide which one you want to call. So it generates an error telling you this.
Both gcc and clang do error: then a sequence of note:s. Usually all of the note:s after an error are important to understanding the error.
To fix this, try calling ::min (fully qualifying the call), or renaming the function to something else, or make your version a better match than std::min (tricky, but doable in some cases), or calling (min)(a,b). The last blocks ADL/Koenig lookup, and also blocks macro expansion (for example, if some OS has injected #define min macros into their system headers) (via # 0x499602D2).
You're running into a name collision with std::min. It is likely included in one of the other standard libary headers that you included, either <iostream> or <string>, my guess is probably the latter. The quick fix is to rename your function. For example, renaming it to mymin works fine. Demo