dynamic linker error with rand() function - c++

I already asked a question about this before but with reference to the following code again
#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>
int rand() throw() {
// get the original rand() function
static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT, "rand");
cout << "Call made to rand()" << endl;
return original_rand();
}
Why does compiling this result in the following error
error: exception specification in declaration does not match previous declaration
Why would this happen? How does the linker know that this is just another rand() function I have declared myself but rather an existing version of rand()?

One of your header files (<iostream> in my case) silently includes <stdlib.h>, which contains the rand() function. The latter does not have any exception specification. In your code you try to overload rand(), but the signature is the same as the one from <stdlib.h> except the exception specifier (which is not part of the function type, so cannot overload on it alone), hence you get a compile-time error (not a linker error, as you mentioned in the question).
If you wonder why the function rand() silently included is also visible in the global namespace (not visible only as std::rand as you may expect), that's because often the C library functions are imported into the standard C++ header files via a direct
// <new_cpp_header>
#include <old_c_header.h>
followed by
namespace std
{
using old_function_from_old_c_header;
}
so the function ends up in both global namespace as well as in namespace std;. This is not a very good practice IMO, but that's how most compilers do it nowadays.
For example, the <cstdio> file has:
// <cstdio>
#include <stdio.h>
namespace std
{
using printf;
// ...
}
so both printf and std::printf are visible, even though you include only <cstdio> (and not <stdio.h>).

Related

Undefined reference to a defined method

So I was trying to access a method that is defined in another class and has the prototype in the header. I'm pretty positive I defined it but it keeps popping up undefined reference to SafeCracker.
Main.cpp
#include <iostream>
#include "mystuff.h"
using namespace std;
void BigDog(int KibblesCount);
int main()
{
cout << SafeCracker(1);
return 0;
}
mystuff.cpp
#include <iostream>
using namespace std;
string SafeCracker(int SafeID)
{
return "123456";
}
mystuff.h
using namespace std;
#ifndef MYSTUFF_H_INCLUDED
#define MYSTUFF_H_INCLUDED
string SafeCracker(int SafeID);
#endif // MYSTUFF_H_INCLUDED
Here it tells you that you have an undefined reference, so you don't really have a problem with the prototype.
Had you forgotten to include the header file that contains the prototype you would have gotten something like
main.cpp: In function ‘int main()’:
main.cpp:8:13: error: ‘SafeCracker’ was not declared in this scope
cout << SafeCracker(1);
Your undefined reference is a linker error. The most likely cause would be that you did not use mystuff.cpp when compiling
If you're compiling from the command line, you should give both files as parameters.
If you're using an IDE that calls the compiler, make sure that the file is part of the project.
For example in Code::Blocks right-click on the file name and go "add to project" (If I remember correctly)
It is also possible that you made a typo in the function declaration in mystuff.cpp (that doesn't seem to be the case here though)
Now there is one important thing about your code you should take note of:
It is very bad practice to put a using namespace in a header file.
using namespace std; in a .cpp source file is mostly up to you, and that using statement will only apply to that particular file.
But if you put it in a header file that is meant to be included through #include , the using there will be forced upon any code that includes it.
Here is an example:
main.cpp
#include <iostream>
// including mystuff.h to use that awesome SafeCracker()
#include "mystuff.h"
// I need to use an std::map (basically an associative array)
#include <map>
// the map of my game
class map
{
int tiles[10][10];
};
int main()
{
// The std map I need to use
std::map<int, int> mymappedcontainer;
// The map of my game I need to use
map mytiles;
// The reason why I need to include mystuff.h
cout << SafeCracker(1);
return 0;
}
Normally, my class map should not be a problem since the map I included from the standard library is inside the namespace std, so to use it you would need to go std::map.
The problem here is that, since mystuff.h has using namespace std; in it, the symbol map is already used, and that creates a conflict.
You do not now who will use your header files, or if you will use them again a long time from now, and maybe then you will want to use name that is already used in the std namespace.
I advise you to use std:: before things taken from the standard libraries instead (std::string instead of just string for example)
PS: In C++, "class" refers to a class data structure, and the functions you made here are not part of any class. You should say "defined in another file" or "defined in another translation unit" instead

C++ compilling errors when using Quadprog++ with Eigen together

this is my first question here, I've searched it all over for a long time yet no solution.
I'm using QUadprog++ to solve a quadratic problem. When I use it in a test alone, it was alright. But when I implement it into my project, which contains Eigen, the Eigen operations will have errors like "Matrix A has no member named ‘lu_inverse’". If I comment the header files of Quadprog++ (Array.hh and Quadprog++.hh) out, the errors just disappear. So I assume that it was a conflict error between the header files of Eigen and Quadprog++. Does anyone have some clue? Thanks in advance!
You can also switch to one of QuadProgpp versions which can work with Eigen types directly: https://github.com/asherikov/QuadProgpp, https://www.cs.cmu.edu/~bstephe1/eiquadprog.hpp; or try an alternative implementation of the same algorithm (also Eigen based) https://github.com/asherikov/qpmad.
if your using namespace quadprogpp; then dont. your different libraries have the same typenames and thats causing the errors you have. It may be a few more characters to type quadprogpp::someFunction(); but its worth it. This is also why you shouldn't ever put a using namespace in a header ever. Its because you pollute all files that include that header with the namespace symbols and name conflicts can ensue which is the same kind of error your having right now.
the Quadprog library is in it's own namespace.
#if !defined(_ARRAY_HH)
#define _ARRAY_HH
#include <set>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
namespace quadprogpp {
enum MType { DIAG };
template <typename T>
class Vector
notice how just after the #includes there is a decleration of namespace quadprogpp{} and everything that is defined in its enclosing brackets will be defined in scope to quadprogpp, so to use any of this library you have to prefix eveything with the namespace name. this is no different than using things from the standard library. I'm quite sure you've written the standard c++ hello world
#include<iostream>
int main()
{
std::cout << "hello world!" << std::endl;
return 0;
}
cout and endl being part of namespace std have to be prefixed with std:: to access them. Many new programmers to c++ dislike this and one of the very first things they google is how to not have to type out namespaces.
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
the next thing new programmers often do is learn to place their definitions in header files and their program logic in cpp files. Thats when they commit the next common mistake.
#ifndef MYHEADER
#define MYHEADER
#include<string>
#include<vector>
#include<iostream>
using namespace std; //Never do this in a header.
doing that pollutes all of your code with everything in the standard library. That may seem like a trivial thing but when you start using another library or perhaps you create your own type that has the same name as things in the standard library that causes name collisions.
That's when the compiler simply cant reason about which Vector you want. But both Quadprog.hh and Array.hh in Quadprog++ are wrapped in namespace quadprogpp to specifically prevent name collision, which is the whole purpose of namespaces. So there is somewhere in your code, likely a header file, where you've made the statement of using namespace quadprogpp;, or some other namespace that defines an Array type, and the compiler can't deduce which type your referring to in your code.
Other than removing your using namespace statements you can also prefix a typename with its namespace qualifer to disambiguate which type your talking about. In your case I'm confident your Array should be declared as quadprogpp::Array arraynamme; rather than simply Array arrayname;

C++ --- Shouldn't these mathematical functions/constants be undefined?

I would not expect the following code that prints the value of sin(pi/2) to work, without the inclusion of an additional header:
#include <iostream>
int main()
{
std::cout << sin(0.5*M_PI) << std::endl;
return 0;
}
and, as expected, upon compilation I get an error reading ‘sin’ was not declared in this scope and a similar error for the use of M_PI.
However, I am confused by the fact that if I include seemingly any boost library header, take just for example the lexical_cast.hpp, and instead run
#include <iostream>
#include <boost/lexical_cast.hpp>
int main()
{
std::cout << sin(0.5*M_PI) << std::endl;
return 0;
}
then the code works and it prints 1.
Why should including this boost header, which contains no definition of M_PI or sin(), allow this constant and function to be defined? Shouldn't I need to include a header, like math.h that includes these things for this to work?
Yes, it should work that way.
The boost headers you tried all have implicit dependencies (pow(), modf(), fmod(), log() etc).
This is a common thing in the C++ compilation model. Nothing to be alarmed by.
Guideline: always explicitly include the headers you directly depend on. And only those.
This prevents portability issues on platforms where the library header dependency tree differs e.g. <algorithms> and <numeric> aren't implicitly included with some other standard library headers (e.g. MSVC)

Functions in namespace std accessible in global scope

Under some situations, it seems like I can access functions that should be in the std namespace without a using or std:: qualifier. So far, I've only seen this occur with functions from the algorithm library.
In the following example, I expect all_of() to be in the std namespace, but this code compiles without error in VS2013 (Microsoft Compiler 18).
#include <iostream>
#include <string>
#include <algorithm>
int main() {
const std::string text = "hey";
std::cout << all_of(begin(text),end(text),islower);
return 0;
}
Changing std::cout to cout without adding a using namespace std or using std::cout generates an "undeclared identifier" error as expected.
What's going on here?
This probably happens due to Argument-Dependent Lookup. The iterator returned by begin(text) and end(text) is probably a class defined in namespace std (or nested in a class in namespace std), which makes namespace std associated with it. Looking up unqualified names for function calls looks into associated namespaces, and finds all_of there.
By the way, this is exactly the same reason why calling begin(text) works, even though the function template begin() is defined in namespace std. text is a std::basic_string, so std is searched.

Dev-C++ compile errors

I want to use "Dev-C++" for compile c++ codes.
So I download and install it, and write this code:
#include <iostream.h>
main () {
cout << "124";
}
but when I compiled it, it said:
In file included from
E:/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
from [myfile path]\Untitled1.cpp:1:
E:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2:
warning: #warning This file includes
at least one deprecated or antiquated
header. Please consider using one of
the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the header
for the header for C++ includes,
or instead of the
deprecated header . To
disable this warning use
-Wno-deprecated.
After I saw errors, I change my code to this code:
#include <iostream>
main () {
cout << "124";
}
but it said again that errors.
I compile first code easily in Turbo C++, BUT in Dev-C++ ...
What can I do?
First, make sure you write out the full definition of main, including the int return type. Leaving out the return type is an old, antiquated practice which doesn't fly these days.
Second, in the new-style headers—the ones missing the .h extension—the standard library is under the std namespace. There are two ways to make your program work:
1. Add an std:: qualifier to cout.
#include <iostream>
int main () {
std::cout << "124";
}
2. Add a using declaration to allow unqualified references to the std namespace.
#include <iostream>
using namespace std;
int main () {
cout << "124";
}
Make sure you put int in front of main () {
I believe any C/C++ program's main() function is required by POSIX and the appropriate language standards to return an int (someone correct me if I'm wrong).
EDIT: Also, be sure to include using namespace std; above int main ().