Adding functions erf() and erfc() to math.h _ basics of C . - c++

I am working with the Borland Turbo C++ compiler in a WINDOWS machine, and wrote a piece of code in C.
I want to use the complementary error function erfc() for one of my calculations.
However, when I run the code, the error is
"Linker error: Undefined symbol _erfc in in module filename.c "
The problem here is erfc() and erf() are supposed to be included in the math.h library.
However, these aren't available in mine.
Can anyone please tell me how I can include these functions in my program ?
Thank you

It's likely that you need to pass some special option to link to the math library.
It's also possible that Borland Turbo C++ doesn't support the erfc() function.
In C, the 1990 ISO C standard didn't include the erfc() function. It was added to the language by the 1999 standard. (I'm not sure about C++.) I think that Borland Turbo++ is fairly old.
Try writing a small program that calls sqrt(). If you can get that to work, and erfc() is still unrecognized, then Borland doesn't support it.
In the latter case, either get a newer compiler (there are a number of free ones, and that's probably a good idea in any case), or find an open source implementation of erfc().

You need to link against the math library. On Unix machines this is done by passing the -lm flag to the linker, which means 'link against a library named libm'. There is probably something similar you need to do for Borland, but I'm not sure on the details. Hopefully this will get you headed in the right direction.

Related

The mess that is ctime, time.h, sys/time.h

I hope some Linux die-hard can answer me how I should write portable (POSIX) code when working with time functions.
Some SO threads suggest that including ctime would be the right thing to do when writing C++ code, whereas you would still include time.h for C code. However, they both define the same function, albeit in a different namespace. Technically you should be able to specify both.
One SO post suggested that one should AVOID using the sys/* based includes alltogether..
.. while this thread implies that sys/time.h must be included before sys/resources.h is included, in particular for BSD-based platforms.
This post says including sys/time.h improves portability. I imagine the poster thinks that it allows you to link more 3rd party libaries that use particular functions like gettimeofday.. however..
gettimeofday() has been discouraged, and is now currently enjoying deprecated status, so I should use clock_gettime() instead. This clock_gettime() is defined in time.h, see https://linux.die.net/man/3/clock_gettime..
.. if one installs and links with libavutil (e.g. as part of ffmpeg-dev) it becomes clear that time.h was created to drive people nuts. Ffmpeg (and some other libs) has it's own time.h, and even timeb.h. It turns out that if ANY .c or .cpp anywhere in your build stack ever includes a time.h, with the include path holding multiple valid entries (including the one for ffmpeg), it may refer to the wrong one, and the declarations are simply replaced. # FFmpeg, the reasoning seems to be that an ugly hack is sufficient to fix the problem. I haven't been that lucky yet. Also, Php-izing all sources does not sound like a solution at all.
Another time.h exists in usr/include/i386-linux-gnu/bits on my system, so this isn't an ffmpeg-only phenomenon either. Simply referring to usr/include/i386-linux-gnu as an include path thus becomes deadly, which is odd when referring to system includes.
I've rewritten my CMake scripts, taking care to use dedicated include folder specs for most of the targets. I've tried including all sorts of permutations of time.h/ctime and sys/time.h in a precompiled header that is referred to throughout the codebase. I still get errors like:
error: field ‘st_atim’ has incomplete type ‘timespec’, struct timespec st_atim;
error: ‘::time’ has not been declared
etc..
So, for a C++ setup linking with many 3rd party dependencies, what is the correct way to make sure everything keeps compiling w.r.t. including time.h? Should I pin the time.h include for the system to the specific platform I'm compiling to? Should I go over all targets that possibly need time.h? Dancing elephants and confetti lie ahead.
Update: The issue seems to be related to the version of C++ as was hinted at in the comments below. I've since updated gcc to 8.3.0 (from 5.4), and I've given up on supporting older c++ compatibility below c++11 on linux. After updating and rebuilding all 3rd party packages (including ffmpeg), I now no longer have the issue I described, but that doesn't mean it's fixed in the sense that it can't occur again for someone else. In fact I think the issue is mainly with how ffmpeg compiles on older compilers and without c++11 explicitly requested, so I'm leaving it open.
I recommend you consider Howard Hinnant's date library that has been accepted into the next version of the C++ standard library (C++20):
https://github.com/HowardHinnant/date
It should work on any platform that supports C++11 onwards.
The Standard version is documented here: https://en.cppreference.com/w/cpp/chrono

Where is the standard library?

I have searched Google but haven't found quite a direct answer to my queries.
I have been reading C++ Primer and I'm still quite new to the language, but despite how good the book is it discusses the use of the standard library but doesn't really describe where it is or where it comes from (it hasn't yet anyway). So, where is the standard library? Where are the header files that let me access it? When I downloaded CodeBlocks, did the STL come with it? Or does it automatically come with my OS?
Somewhat related, but what exactly is MinGW that came with Cobeblocks? Here it says
MinGW is a C/C++ compiler suite which allows you to create Windows executables without dependency on such DLLs
So at the most basic level is it just a collection of "things" needed to let me make C++ programs?
Apologies for the quite basic question.
"When I downloaded CodeBlocks, did the STL come with it?"
Despite it's not called the STL, but the C++ standard library, it comes with your c++ compiler implementation (and optionally packaged with the CodeBlocks IDE).
You have to differentiate IDE and compiler toolchain. CodeBlocks (the Integrated Development Environment) can be configured to use a number of different compiler toolchains (e.g. Clang or MSVC).
"Or does it automatically come with my OS?"
No, usually not. Especially not for Windows OS
"So, where is the standard library? Where are the header files that let me access it?"
They come with the compiler toolchain you're currently using for your CodeBlocks project.
Supposed this is the MinGW GCC toolchain and it's installed in the default directory, you'll find the libraries under a directory like (that's what I have)
C:\MinGW\lib\gcc\mingw32\4.8.1
and the header files at
C:\MinGW\lib\gcc\mingw32\4.8.1\include\c++
"So at the most basic level is it just a collection of "things" needed to let me make C++ programs?"
It's the Minimalist GNU toolchain for Windows. It usually comes along with the GCC (GNU C/C++ compiler toolchain), plus the MSYS minimalist GNU tools environment (including GNU make, shell, etc.).
When you have installed a C++ implementation you'll have something which implements everything necessary to use C++ source files and turn them into something running. How that is done exactly depends on the specific C++ implementation. Most often, there is a compiler which processes individual source file and translates them into object files which are then combined by a linker to produce an actual running program. That is by no means required and, e.g., cling directly interprets C++ code without compiling.
All this is just to clarify that there is no one way how C++ is implemented although the majority of contemporary C++ implementations follow the approach of compiler/linker and provide libraries as a collection of files with declarations and library files providing implementations of these declarations.
Where the C++ standard library is located and where its declarations are to be found entirely depends on the C++ implementations. Oddly, all C++ implementations I have encountered so far except cling do use a compiler and all these compilers support a -E option (although it is spelled /E for MSVC++) which preprocesses a C++ file. The typically quite large output shows locations of included files pointing at the location of the declarations. That is, something like this executed on a command line yields a file with the information about the locations:
compiler -E input.cpp > input.ii
How the compiler compiler is actually named entirely depends on the C++ implementation and is something like g++, clang++, etc. The file input.cpp is supposed to contain a suitable include directive for one of the standard C++ library headers, e.g.
#include <iostream>
Searching in the output input.ii should reveal the location of this header. Of course, it is possible that the declarations are made available by the compiler without actually including a file but just making declarations visible. There used to be a compiler like this (TenDRA) but I'm not aware of any contemporary compiler doing this (with modules being considered for standardization these may come back in the future, though).
Where the actual library file with the objects implementing the various declarations is located is an entirely different question and locating these tends to be a bit more involved.
The C++ implementation is probably installed somehow when installing CodeBlocks. I think it is just one package. On systems with a package management system like dpkg on some Linuxes it would be quite reasonable to just have the IDE have a dependency on the compiler (e.g., gcc for CodeBlocks) and have the compiler have a dependency on the standard C++ library (libstdc++ for gcc) and have the package management system sort out how things are installed.
There are several implementations of the C++ standard library. Some of the more popular ones are libstdc++, which comes packaged with GCC, libc++, which can be used with Clang, or Visual Studio's implementation by Microsoft. They use a licensed version of Dinkumware's implementation. MinGW contains a port of GCC. CodeBlocks, an IDE, allows you to choose a setup which comes packaged with a version of MinGW, or one without. Either way, you can still set up the IDE to use a different compiler if you choose. Part of the standard library implementation will also be header files, not just binaries, because a lot of it is template code (which can only be implemented in header files.)
I recommend you read the documentation for the respective technologies because they contain a lot of information, more than a tutorial or book would:
libstdc++ faq
MinGW faq
MSDN

How can I compile Gnu C in windows

Too those who know how, this may be a stupid question, but I'll be asking it anyway because I need some pointers.
The library I'm trying to compile is the SPro toolkit for speech signal processing which is written in (for lack of a better description) Gnu C++
It's a library written for unix and I want to compile it in windows. As much as an object exercise in porting code from, as anything.
Toward that end I have installed code::blocks and a MinGW compiler. I read that I could also use cgywn and that this would be introducing a layer interpreting the gnu c before executing it natively, but let me leave that to the side for the moment.
The first issue I ran into was that the #includes need a little love - ok no problem with that.
But now I find that
scopy.c|462|error: 'SIZEOF_SHORT' undeclared (first use in this function)|
I also installed visual Studio C++ and get the same.
I gather that SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_LONG, SIZEOF_FLOAT and SIZEOF_DOUBLE would be declared, in a header or somewhere.
Unfortunalty I don't have any idea where, so have no idea what to include to have access to the definitions.
What should I include?
Do I need to define these constants myself as I am in a different environment?
Also I may be barking up the wrong tree, any help is appreciated.
#define SIZEOF_SHORT sizeof(short)
#define SIZEOF_CHAR sizeof(char)
Repeat for all other types.

Linking code compiled with VC++10 to code compiled with VC++9

Our project uses VC++9 with VS2008, and we want to make the switch to VC++10 with VS2010 to use the new features. Unfortunately, some of our dependencies were built with VC++9, and recompiling them with VC++10 is not possible at the moment for various reasons. Since we really want to make the switch, is there was a way to simply link with those libraries, or is there no compatibility between VC++10 and VC++9 binaries?
EDIT: The actual dependencies are BWAPI and BWTA. In the case of BWAPI, it's not a problem, but BWTA depends in CGAL, and that's what's giving us trouble. Trying to link with it yields a bunch of linking errors.
In general you are out of luck unless the dependencies are COM modules or dlls that export only "pure" C functions.
Visual Studio releases are allowed to break ABI compatibility. This means the exported and internal signature of C++ classes is different, and passing for example a std::string from a binary compiled with one version to a binary compiled with a different version might not have the expected result. In short: do not rely on this working. If it does, you're lucky, but in "undefined behavior" territory at the runtime level. Just fix your code to build with VS2010. It's probably broken to start with.
well in the case of a 3rd party lib that you cannot change, the typical answer is to wrap them with a simple dll that is built with VC2008 and calls the 3rd party for you. You then have control over what is exposed, so you can fall back to a 'standardised' mechanism that works with both linkers. This is almost always C function calls as C is very standardised.
The problem is MS changing the ABI of compiled C++, and I guess with the standards committee not providing a standard way of calling C++ binaries.
Looking at GCAL this doesn't seem to be a good answer for you, the best you can do in such cases is to contact GCAL and wait for a rebuilt binary.
But I just checked - its open source, rebuild it yourself. Not only that, it already supports VS2010 so rebuild should be easy.

Name mangling problems when using GNU linker to link to VC++ compiled library

In asking this question, I'm looking for either better understanding of the situation or preferably a solution.
I'm created C++ code and I would like to be able to use the Eclipse CDT IDE rather than Visual Studios, (my workplace is more Eclipse friendly). This implies that, practically speaking, I must use the GNU tool chain to compile my code. For the project at hand, I must link to a library called HyDE.lib that was compiled with the Visual Studios compiler. Of course, the problem that I run into is that the GNU linker can't find the appropriate symbols in HyDE because (I presume) both compilers use different name mangling schemes.
So how do I get around this?
Current thoughts:
The most obvious thing would be to recompile HyDE.lib with the GNU tool chain. This is proving to be more complicated than perhaps it's worth. However there is one avenue that I haven't investigated here. We have a cmake file that supposedly can build to unix... is there some way to have cmake instead use Cygwin GNU? I really know nothing about cmake (and very little about make), so a reference to good information would be nice.
I could connect Eclipse CDT to the Window compiler tools. Yes, but best I can tell this is not easy, and I would potentially lose debugging and maybe even code completion. Then there is Eclipse Wascana, but I read a recent blog that indicated that the Wascana community is waining.
Is there any sort of library demangler-remangler? I imagine a program that I would give a Windows compiled library too, and the program would pick out the symbols, demangle them, and then create a library that had the same symbols, but mangled in the GNU way. At this point I'm making stuff up, so maybe someone could help me better understand name mangling here.
Any ideas?
Unless you place most of the code in HyDE.lib with extern "C" blocks, then your best bet is to recompile it with G++. Even if you do place it in extern "C" blocks, I would still reccomend compiling it with G++ as it usually (but not always) has better support for standards than MSVC.
As an alternative, complete the compilation of the library into a .dll file and use that. Just make sure to put entry points in extern "C" blocks.