Unable to link Embarcadero XE4 project when using floorf() function - c++

I need to use the floorf() function defined in Math.h and while I can compile the module where this is used successfully in my XE4 project, I receive this error when linking:
[ilink32 Error] Error: Unresolved external '_floorf' referenced from <myfilename>.OBJ
[ilink32 Error] Error: Unable to perform link
This makes no sense - the compiler obviously knows where the function is declared as it opens Math.h when I control-click on the floorf() function. and I've included #include in the .cpp file. What do I need to get this working? I really need to use this standard math function.

Linking with math library is not enabled by default in some compilers.
gcc: why the -lm flag is needed to link the math library?

I use BDS2006 so this may not help but:
try to use floor() instead of floorf()
if you have ambiguility problems use float(floor(float(x)));
try to include instead of or the other way around to see if it helps
do you use any namespace? (try to use ::floor())
didn't you forget some ;,{,},}; ? especially in struct/class/namespace
do you use #defines ?
borland/embarcadero has sometimes problems with code inside defines
very rarely it compile it wrongly so the code does not work as it is written
did see this few times usually swapping/inserting some lines (even empty) helps
where do you use the floorf function (cpp file or unit or form)?
if you add unit file to the project (with your own stuff not Window/Form code)
then it is presumed to be VCL/machine generated stuff like Form not standard C/C++ file
and it is compiled/linked differently
if this is the case remove the file from project
and add include of it to one of the Form cpp/h files where it is needed
I saw this behavior in BCB5,BCB6,BDS2006
do you use some #defines that collide with math internal compilation tokens?
some defines could be used internally to enable//disable parts of code inside math
so if you define the same prior to math include you can mess with it
do not use tokens like _math,_floor...
how do you name your own functions
if they collide with VCL names then weird stuff starts to happen
the typical is own Draw() functions with collision with internal TForm::Draw
no bug is reported but sometimes the code does not work (even if call operands are not the same)
last saw this on BCB6
just rename those to draw() and you will be fine unless you are bound to some naming scheme
My bet is the point 6 saw it many many times back in my teaching times

Related

Receiving the error "undefined symbol" when loading C++ dynamic library from C executable

I am trying to write a plugin for a popular program whose code and compilation process I do not have control over. The program is written in C. However, I have written parts of my plugin in C++, since I use the QT5 library for graphics capabilities. The functions that the C program calls are written in C.
When the C program tries to load the plugin (shared library), it produces this error:
dlopen('build/libfoo.so') failed: build/libfoo.so: undefined symbol: _ZTV13JoystickPanel
JoystickPanel is a class in the C++ part of the program.
I've tried rewriting parts of the program in C, but the error was unaffected. I know that I could rewrite the entire program in C, but I'd rather not have to switch to another, more C-friendly GUI framework. I've also opened up libfoo.so in a text editor and search for JoystickPanel, but it appears to be mangled as _ZN13JoystickPanel.
Are there any compiler options or solutions that I'm missing?
I have no idea what _ZN13JoystickPanel means, since it's not apparently a valid mangled C++ name. It should perhaps be _ZN13JoystickPanelE, which would translate to JoystickPanel. That'd be symbol name for sure, but without much meaning anyway. You must have truncated something: I tried quite a bit and just can't generate an object file that would include _ZN13JoystickPanel as the complete symbol. It's just a prefix, there should be a "second half" attached to it - was there?
But _ZTV13JoystickPanel is the vtable for the JoystickPanel class. It's missing because you didn't provide implementations for all the virtual methods of the JoystickPanel class. Most likely, you didn't invoke moc properly, or forgot to compile and link its output.
You need to show a complete build script for your plugin at the very least (the .pro file, or CMakeLists.txt). You'll also need to provide a github link to your project (I presume it's open source).
The symbols you want to find in the compiled output are at least _ZTV13JoystickPanelD#Ev - virtual destructors, where # is a digit, _ZTV13JoystickPanel - the virtual method table,
Those symbols may be absent when compiled with optimization and/or LTCG, but also absent will be references to them.
You may wish to delete the build folder and rebuild your project, just to be sure. qmake is bad at dependency generation for the makefiles it produces, so if you use it, I suggest switching to cmake + ninja.
Apparently, I'd forgetten to put the #include "moc_controller.cpp" line at the bottom of a file that needed it.
For anyone else chasing this issue while using Qt on CMake, consider making sure that the proper lines are added.

How can I find out the references to a C++ symbol

I am working on an existing big C++ code base (more than 1 million line of code). I need to remove some part of the code deemed not useful. However, when I just exclude that part of code from the build process (i.e. not to compile them), eventually I got "undefined references" error in linking for some symbols (class function names) I removed.
A problem rose when I tried to find out where in other code have the references. Using Cscope or OpenGrok, I can find out a few explicit references but does not really help after removing such references. There are lots of other cases indirectly referring to the symbol I removed, for example:
virtual functions overridden in child class
"typedef" defined other symbol to refer to this missing symbol.
My question is: is there any gcc/g++ option I can turn on to have a output of all references (that gcc/g++ is aware of) direct or indirect to the symbol I removed?
If no such gcc/g++ option, is there any other tool that can produce such output?
Thanks.
Removing the compilation units (c or cpp files) from your project does not completely remove them. Those are typically just the definitions of functions and classes. The declarations of those functions and classes still exist in headers which are likely still being included in other compilation units.
Track down where these things are declared (typically in header files) and either comment them out in the headers or stop including the headers entirely if you don't need anything within them for your project.
For example:
If you are removing foo.c from a project, make sure any instance of #include "foo.h" has been removed from all other c/cpp files
You can instruct LD to emit a linker map containing a cross reference table using the flags -Map=path/to/my_mapfile.map and --cref. More info here:
https://sourceware.org/binutils/docs/ld/Options.html
The map file is very long and terse, but it usually has enough information to help you pinpoint exactly why a given symbol is still being referenced.

How can I ensure no code uses an API?

I want to ban use of iostreams in a code base I have (for various reasons). Is there a way I can inspect symbol files or force the compiler to emit an error when that API is used?
A simple approach is provide a dummy iostream implementation that does nothing but throw a compile-time error.
The following example assumes a GCC toolchain - I imagine the process is similar with other compilers.
First, create your dummy iostream file:
#error 'Use of iostream is prohibited'
Some dummy application code to demonstrate:
#include <iostream>
int main (int argc, char** argv) {
std::cout << "foo!";
return 0;
}
Compile as follows (assuming the dummy iostream and main.cpp are in the working directory):
g++ -I. main.cpp
Compilation fails with the following errors:
In file included from main.cpp:2:0:
./iostream:1:2: error: #error 'Use of iostream is prohibited'
main.cpp: In function 'int main(int, char**)':
main.cpp:4:2: error: 'cout' is not a member of 'std'
Added bonus: symbols usually declared in that file (e.g. cout here) are undefined, and so get flagged in the compiler output as well. As such, you also get pointers to exactly where you're using your prohibited API.
UPDATE: Instructions for Visual C++ 2012.
As #RaymondChen points out in the comments below, a solution tailored to Visual C++ is likely more useful to the OP. As such, the following outlines the process I went through to achieve the same as the above under Visual C++ 2012.
First, create a new console project, using the above C++ code. Also create the dummy iostream header I described above, and place it in a directory somewhere easy to find (I put mine in the main project source directory).
Now, in the Solution Explorer, right click on the project node and select "Properties" from the drop-down list. In the dialog that appears, select "VC++ Directories" from the tree on the left. Prepend the directory containing the dummy iostream file into the list of include directories that appears on the right, separated from the other directories with a semicolon:
Here, my project was called TestApp1, and I just prepended its main directory to the $(IncludePath) that was already there. Note that it is important to prepend rather than append - the order of the directories in the list determines the search order, so if $(IncludePath) appears before your custom directory, the system header will be used in preference to your dummy header - not what you want.
Click OK, and rebuild the project.
For me, doing so resulted in the following errors in the VC++ console (edited slightly for brevity):
error C1189: #error : 'Use of iostream is prohibited'
IntelliSense: #error directive: 'Use of iostream is prohibited'
IntelliSense: namespace "std" has no member "cout"
Note that IntelliSense also picks up the (now) illegal use of cout - it is highlighted with an error mark in the editor.
This is a nasty hack, but it should work.
The C standard (and consequently the C++ standard as well) allows preprocessor tokens in #include directives. This is also known as "computed includes".
Thus, adding something like -Diostream to CFLAGS inside your makefile (or to compiler options in your IDE's project settings) should reliably break the build if someone tries to use iostream.
Of course, with an empty macro, the error message will not be very informative, but you could instead use something like -Diostream=DUDE_DONT_USE_IOSTREAM, which will show an error like: DUDE_DONT_USE_IOSTREAM: file not found.
It's also something that you can turn off again without much hassle if you change your mind later. Just remove the build option.
Your idea to inspect symbol files is feasible and very realistic. virtual ~ios_base(); is a single method that all streams will inherit, and which can't easily be inlined since it's virtual and non-trivial. Its presence in an object file is therefore a very strong indication of IOstream use.
In addition to compiler-assist method mentioned by Mac you can use generic search functions. For example (I assume zsh shell - for bash doesn't have ** and on Windows you need to find how to do it with Powershell):
# Find all mentioning on `iostream` `cin` in all files ending in cc in all subdirectories of current directory
grep iostream **/*.c
grep cin **/*.cc
If you don't want to/can't use command line you can use your favourite editor and search for unwanted symbols.
I usually combine both methods:
Compilation, especially of large project with large number of templates, is slow while searching is fast so you're more productive with search
On the other hand search operates is not exact and might miss something. So I'd use header tricks to verify solution done in previous step
As final verification you can search for symbols after compilation. It is especially useful if you compile with no optimization. You can use objdump or similar (depending on platform) and watch for imported symbol (this works if you don't say link statically to something using iostreams).
No, not at all. For a very limited subset, you could provide your own definitions, causing the linker to error at the duplicates. This would be very undefined behaviour though. And a good portion is templates that aren't susceptible to this. Without doing drastic things like deleting the iostream header, or using a compiler like Clang and modifying the source code, there's really nothing you can do.

In xcode when including cmath get error: '::acos' has not been declared, etc

I get the following errors when trying to build a small and simple project that includes <cmath> in Xcode:
cmath: '*' has not been declared
'::acos' has not been declared
In file included from /Xcode4/Projects/libraryLAFMath/Classes/libraryLAFMath.cp
In file included from /Xcode4/Projects/libraryLAFMath/Classes/libraryLAFMath.h
'::acos' has not been declared in /Xcode4/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/usr/include/c++/4.2.1/cmath
...
The error log complains about all the other math functions as well, sin, pow, etc, not just acos. I looked inside cmath source code and it references the globally defined corresponding math functions from math.h, ie ::acos etc. Since the root error complains about the non-existance of ::acos one would assume that math.h can't be found, but a) it exists, and b) I'd get a different error complaining that math.h can't be found.
The source code is as follows:
libraryLAFMath.cp:
#include "libraryLAFMath.h"
libraryLAFMath.h:
#include <cmath>
struct libraryLAFMath {
void test() {
double a = std::acos(0);
}
};
Now, I have another project from an outside source that uses cmath and compiles fine. I tried comparing build settings between these two projects but they are pretty much the same. I am using LLVM GCC 4.2 compiler, but get similar result when using GCC 4.2, so it's not a compiler settings issue I believe.
I'm new to Xcode development and any help is appreciated.
There is a file I have in my project named Math.h with a capital M, and it seems the compiler gets confused and tries to include Math.h instead of math.h.
I posted this answer on an alternate thread on the topic, but thought it worth including here as well:
I had this problem - it was driving me crazy but I tracked down the cause, and it was a little different than what I've seen reported on this issue.
In this case, the general cmath header (or math.h - the error and solution occur in C++ or C) had architectural environment switches to include architecture specific math subheaders. The architecture switch (environment variable) hadn't been defined, so it was punting and not actually including the headers that truly defined the math functions.
So there was indeed a single math.h or cmath.h, and it was included, but that wasn't enough to get the math functions. In my case, rather than define the architectural variable, I instead found the location of the correct sub math headers and added them to my compile path. Then the project worked!
This seems to be an issue that comes up a lot when porting Linux projects to OS-X. I'd imagine it might occur anytime a project was moved betwee platforms such that the standard library headers are arranged differently.

Linker error with Duplicated Symbols, SWIG and C++ Vectors

I came across this error trying to compile a shared object from 2 sets of objects. The first set contains one .os object compiled from one cpp file generated by SWIG. The second set is contains all of the .so files from the individual files that make up the interface to be wrapped.
$g++ -shared *.os -o Mathlibmodule.so
ld: duplicate symbol std::vector<int, std::allocator<int> >::size() constin Mathlib_wrap.o and Capsule.o
The swig c++ wrapper (Mathlib_wrap.o's source file) is machine generated and nasty to look at, with lots of #defines to make it extra hard to trace. It looks like the redefinition is present in all of the object files in the second set. I've traced through the headers included in all those files, and the seem to be #pragma once'd.
What advice do people have for tracking down what/where the problem is?
I'm going to assume that you've properly #ifndef/#define blocked all of the header files in your C++ library, after that I'd check your .i file to make sure you aren't actually duplicating some declaration there somehow. Maybe try importing a small small piece of the library first or something.
I have run into issues like this before, but its always turned out to be something silly I'd done. Nothing specific I'm afraid.
Post the .i file maybe, donno.
When in doubt, assume that the error means what it says: Actual code was generated for vector<T>::size within each of those object files. This of course seems very unusual because you would expect the function to be expanded inline in each file it was being used in.
If it weren't std::vector the first thing I would say is that a function defined in a header wasn't marked inline correctly. The compiler would generate the code in each source file that included that header. What version of g++ are you using, and are you using a custom standard library/vector implementation?
One thing to check is to compile with optimization on (-O2) and see if that causes it to inline the calls within creating an actual function.
Another possibility is that you're including two different versions of the vector include, and violating the one definition rule. At that point I wouldn't rule out a linker error such as you're seeing.