Why C libraries for Linux and Windows are different? - c

I have tried to run the functions "strlwr", "strupr", "strcmpi", "strrev" from the string.h under Ubuntu and the gcc compiler; getting the next message:
warning: implicit declaration of function ‘strupr’ [-Wimplicit-function-declaration]
as well
(.text+0x84): undefined reference to `strupr'
Once I tried over Windows, same compiler, everything works perfectly.
I looked over the string.h in linux under "/usr/include" which states that was part of the GNU C library ISO C99 7.21 string handling (also tried to compile with the -std=c99, din't work) and I've learned from the header file that I could use the "strcasecmp" function, instead of the "strcmpi".
Can not do the same in Windows (look under the code of the header file) since the headers and libraries files are kind embedded under the compiler code, Am I right?(1)
Again searching for the string.h file in Linux, I have found nearly 50 files with the same name under different paths such as /usr/include/linux;
/usr/include/x86-64-linux-gnu/bits others under the directories of Oracle VB and the Arduino directory.
Why are so many files that handle the strings in C but doing in different fashion? How does the compiler knows which one to take in order to do the work? Is there any way, under the C file or during the compile process to define one of the multiple headers files?(2)
Am I using out of date headers and libraries, Is there any "official" source to know if any library have come depreciated? How to know what are under the Windows headers and libraries?(3)
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) is what I am using and Windows 8.

Related

GCC: compiling an application without linking any library

I know how to compile a C application without linking any library using GCC in bare metal embedded application just setting up the startup function(s) and eventually the assembly startup.s file.
Instead, I am not able to do the same thing in Windows (I am using MINGW32 GCC). Seems that linking with -nostdlib removes also everything needed to be executed before main, so I should write a specific startup but I did not find any doc about that.
The reason because I need to compile without C std lib is that I am writing a rduced C std lib for little 32 bits microcontrollers and I would like to test and unit test this library using GCC under Windows. So, if there is an alternative simplest way it is OK for me.
Thanks.
I found the solution adding -nostdlib and -lgcc together to ld (or gcc used as linker). In this way the C standard lib is not automatically linked to the application but everything needed to startup the application is linked.
I found also that the order of these switches matters, it may not work at all, signal missing at_exit() function or work without any error/warning depending by the order and position of the options.
I discovered another little complication using Eclipse based IDEs because there are some different approaches in the Settings menu so to write the options in the right order I needed to set them in different places.
After that I had a new problem: I did not think that unit test libraries require at least a function able to write to stdout or to a file.
I found that using "" and <> forces the compiler and linker to use the library modules I want by my library and the C standard library.
So, for instance:
#include "string.h" // points to my library include
#include <stdio.h> // points to C stdlib include
permits me to test all my library string functions using the C stdlib stdout functions.
It works both using GCC and GCC Cross Compilers.

C - tcc finds error in commdlg.h?

I'm attempting to write a C program incorporating OPENFILENAME and of course I need the header file. So, following the instructions provided with tcc, I downloaded the header files MinGW uses for the Win32 API (and the library files) and put them in the appropriate directories as instructed. However, when I come to compile the program, I get the following error:
In file included from sw1.c:2:
c:/prg/tcc/include/winapi/commdlg.h:503: declaration list expected
This seems rather odd, given it's a standard header. So, I look up the line and it's typedef __AW(CHOOSECOLOR) CHOOSECOLOR,*LPCHOOSECOLOR;, which doesn't look very valid to me but then I'm not really a C expert and I've mainly been writing in Linux. I have no idea why it's going wrong though and no knowledge of how to fix it? Is it a bug in tcc?
As evidence that this should be possible, here is the appropriate passage from the tcc readme:
Header Files:
The system header files (except _mingw.h) are from the MinGW
distribution:
http://www.mingw.org/
From the windows headers, only a minimal set is included. If you need
more, get MinGW's "w32api" package.
I understand that this question is similar to Error when including Windows.h with TCC but my "windows.h" file does work - it's just this that doesn't.
Does anyone know how to solve this? I'm really at a loose end!

GCC linked library for compile

Why do we have to tell gcc which library to link against when that information is already in source file in form of #include?
For example, if I have a code which uses threads and has:
#include <pthread.h>
I still have to compile it with -pthread option in gcc:
gcc -pthread test.c
If I don't give -pthread option it will give errors finding thread function definitions.
I am using this version:
gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
This may be one of the most common things that trip up beginners to C.
In C there are two different steps to building a program, compilation and linking. For the purposes of your question, these steps connect your code to two different types of files, headers and libraries.
The #include <pthread.h> directive in your C code is handled by the compiler. The compiler (actually preprocessor) literally pastes in the contents of pthread.h into your code before turning your C file into an object file.
pthread.h is a header file, not a library. It contains a list of the functions that you can expect to find in the library, what arguments they take and what they return. A header can exist without a library and vice-versa. The header is a text file, often found in /usr/include on Unix-derived systems. You can open it just like any C file to read the contents.
The command line gcc -lpthread test.c does both compilation and linking. In the old days, you would first do something like cc test.c, then ld -lpthread test.o. As you can see, -lpthread is actually an option to the linker.
The linker does not know anything about text files like C code or headers. It only works with compiled object files and existing libraries. The -l flag tells it which libraries to look in to find the functions you are using.
The name of the header has nothing to do with the name of the library. Here it's really just by the accident. Most often there are many headers provided by the library.
Especially in C++ there is usually one header per class and the library usually provides classes implementations from the same namespace. In C the headers are organized that they contain some common subset of functions - math.h contains mathematical operations, stdio.h provides IO functions etc.
They are two separate things. .h files holds the declarations, sometimes the inline function also. As we all know, every functions should have an implementation/definition to work. These implementations are kept seperately. -lpthread, for example is the library which holds the implementation of the functions declared in headers in binary form.
Separating the implementation is what people want when you don't want to share your commercial code with others
So,
gcc -pthread test.c
tell gcc to look for definitions declared in pthread.h in the libpthread. -pthread is expanded to libpthread by linker automatically
there are/were compilers that you told it where the lib directory was and it simply scanned all the files hoping to find a match. then there are compilers that are the other extreme where you have to tell it everything to link in. the key here is include simply tells the compiler to look for some definitions or even simpler to include some external file into this file. this does not necessarily have any connection to a library or object, there are many includes that are not tied to such things and it is a bad assumption. next the linker is a different step and usually a different program from the compiler, so not only does the include not have a one to one relationship with an object or library, the linker is not the compiler.

How to use C only features in latest compilers?

I am using codeblock 13.12 and it uses mingw (GCC 4.7 & 4.8 Series)
It supports call by reference (func1(int &a)) eventhough I am selecting C project and not CPP project. If I am not mistaken, there is no concept of call by reference in C and everything is call by value even if it is making use of pointers.
My question is how to use C only features? Any settings for this? I saw that in toolchain it is using mingw32-gcc.exe for c compilations.
How to know which compiler version (Like C11, C99 etc) it is really using?
Name your files with an extension of .c. And definitely not .cc or .cpp
Compile with gcc as the command line, not g++
And if in doubt, use the -std= command line parameter to force the flavor of C you want (e.g. -std=C90, -std=C99, or even -std=C11 ). There's also -ansi.
Also, a cheap and dirty way to validate if your code is getting compiled as C and not C++ is to add this block of code within your source code. If it's C++, then the compiler will generate an error.
#ifdef __cplusplus
int compile_time_assert[-1];
#endif

mrand not in mingw?

I use dev c++ for my c projects,because it's simple for me.I installed it with the mingw extension.Well,I included stdlib.h and made a call to mrand which according to manpages belongs to that header but I got a linker error.I looked in mingw's headers and found no declaration for mrand although the glibc has one in stdlib.Am I missing something?I thought mingw and gcc were the same.If they are different I suppose that there isn't a way to get gcc's full power.Right?Thank you.
mrand is not part of the standard C library, nor is it present in standard Linux manpages. Whatever compiler you previously used may have had it as a proprietary extension, but since you haven't mentioned which (it's not GCC or MSVC, at least), I can't tell what mrand is supposed to do, and so it's hard to suggest an alternative function to use.
Note that glibc does offer a mrand48(). Since this is a POSIX function, not a standard C function, it may or may not be present in other C libraries - but note that this is a function of the C library (glibc), not the compiler (gcc/mingw).

Resources