Simple .c file fails to compile pthreads.h - c

I'm a longtime python hobbyist porting a script over to c. I believe there is something wrong in the environment preventing the code from compiling. Research elsewhere leads me to believe it has something to do with posix header files? Maybe something with macros? I'm insufficiently experienced in c to figure it out.
The relevant snippet is here:
pthread_t id;
thread_create(&id, NULL, refreshqb,NULL);
void *status;
pthread_start(id, (void**)&status);
The error I receive is this.
t.c:91:4: warning: implicit declaration of function 'thread_create' is invalid in C99
[-Wimplicit-function-declaration]
thread_create(&id, NULL, refreshqb,NULL);
^
t.c:93:4: warning: implicit declaration of function 'pthread_start' is invalid in C99
[-Wimplicit-function-declaration]
pthread_start(id, (void**)&status);
^
2 warnings generated.
Undefined symbols for architecture x86_64:
"_pthread_start", referenced from:
_main in t-0d3a02.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Support for pthreads must be explicitly enabled when compiling your code. It looks like you're using clang, so just add the -pthread flag when you compile using clang.

Please try using pthread_create, along with including correct posix library header or "#include <pthread.h>".

Related

clang not recognizing unitialized pointer found in static library

I've found a curiosity when compiling with clang (on a MacBook, if it helps). Suppose I have two files:
blah.c
int *p;
main.c
#include <stdio.h>
extern int *p;
int main() {
printf("%p\n", p);
return 0;
}
If I compile with
clang blah.c main.c
everything works out fine. However, if I do
clang -c blah.c
ar rcs libblah.a blah.o
clang main.c libblah.a
I get a linker error:
Undefined symbols for architecture x86_64:
"_p", referenced from:
_main in test-4bf0d6.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Interestingly, if I initialize the variable in blah.c,
#include <stddef.h>
int *p = NULL;
the error goes away.
Also, compiling with gcc doesn't produce this behavior. What exactly is going on with clang here?
Here's the output from clang --version:
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
What exactly is going on with clang here?
TL;DR: Your Clang has a bug. You can probably work around it without modifying your code by adding -fno-common to your compile options.
More detail
Both variations of your code are correct, and as far as the C language specification is concerned, they have the same meaning. On my Linux machine, GCC 8.5 and Clang 12 both accept both variations and successfully build working executables, whether blah.o is linked directly or from a library.
But if you use nm to examine the library built with and without the initializer for p, you will likely get a hint about what is happening. Without an initializer, I see (with either compiler) that p has type 'C' (common). With an initializer (to null), I see that it has type 'B' (BSS).
That is reflective of a traditional behavior of Unix C implementations: to merge multiple definitions of the same symbol as long as no more than one is defined with an explicit initializer. That is an extension to standard C, for the language requires that there be exactly one definition of each external symbol that a program references. Among other things, that extension covers the common error of omitting extern from variable declarations in headers, provided that the header does not specify an initializer.
To implement that, the toolchain needs to distinguish between symbols defined with an explicit initializer and those defined without, and that's where (for C) symbol type "common" comes in -- it is used to convey a symbol that is defined, but without an explicit initializer. Typical linker behavior would be to treat all such symbols as undefined ones if one of the objects being linked has a definition for that symbol with a different type, or else to treat all but one of them as undefined, and the other as having type B (implying default initializtion).
But the MacOS development toolchain seems to have hatched a bug. In your example, it is erroneously failing to recognize the type C symbol as a viable definition when that appears in a library. The issue might be either in the Clang front end or in the system linker, or in a combination of both. Perhaps this arrived together with Apple's recent tightening (and subsequent re-loosening) of the compiler's default conformance settings.
You can probably work around this issue by adding --fno-common to your C compiler flags. GCC and Clang both accept that for disabling the symbol merging described above, and, at least on my machine, they both implement that by emitting the symbol as type B when it is defined without an explicit initializer, just as if it had been explicitly initialized to a null pointer. Note well, however, that this will break any code that is presently relying on that merging behavior.

Treating 'c' input as 'c++' when in C++ mode

sorry for my question, I get homework in my university, I need make a programm in C programming language, but when I start with on Mac OS (in school we use OpenSolaris I think) I got this problem, can I fix it without Unix installation?
Console output: (screenshot)
MBP-Maxim:cv01 maxim$ g++ main.c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You have two problems:
g++ is a C++ compiler. Your source file is C, not C++. Use gcc to compile C source code.
The file you are trying to compile doesn't have a main function, which is required to generate an executable. Write one.
Just to elaborate more on #duskwuff-inactive- reply
For warning like this clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
Your file name is main.c instead of main.cpp or main.cc when compiling with g++ compiler or use gcc compiler for main.c.

C/OSX/clang confusion: "symbol(s) not found" happening at link time instead of compile time

I have a question, but I'm not sure if it's about C, clang or OSX.
When I compile a simple GLUT program like so:
clang test.c -framework OpenGL -framework GLUT
And I intentionally insert a function call that doesn't exist, like so:
thisFunctionIsNotDefinedAnywhere();
I get an error, as expected. But here's the rub -- I don't get the error until link time!
Undefined symbols for architecture x86_64:
"thisFunctionIsNotDefinedAnywhere" referenced from:
_main in test-e099d2.o
ld: symbol(s) not found for architecture x86_64
Why is this? Is this because pre-C99 there were implicit declarations? I've been programming for a long time and have never run into this before. Is it because I've been spoiled on GCC and MSVC which (I seem to remember) cause a compiler error in this situation? Or does it have to do with how framework linking works in OSX, which I am new to?
I appreciate any clarification!
As expected, this gives a warning with a recent version of clang. I tried it with the version that comes with Xcode 6.1, and got this compiler output:
$ clang test.c
test.c:2:5: warning: implicit declaration of function 'thisFunctionIsNotDefinedAnywhere' is invalid in
C99 [-Wimplicit-function-declaration]
thisFunctionIsNotDefinedAnywhere();
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_thisFunctionIsNotDefinedAnywhere", referenced from:
_main in test-376416.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Since using undeclared functions is legal in C, the compiler message can't be an error. But it does show a clear warning, without specifically enabling warnings with command line options.
Because of implicit function declaration, if you enable warnings then you would be warned that thisFunctionIsNotDefinedAnywhere(); is implicitly declared, returning int by default.
If you add a function prototype, then the warning will be gone, but then at the link stage, the compiler wont find the function definition, and issue the error.

Warnings while compiling a C library

I am trying to compile a C library and I am getting a loy of warning while doing it. Though the compiled library is working properly, I am still a bit apprehensive about the warnings. I googled all the warnings, but the relevant search results are hard to come by.
The warnings are:
main(){printf("osx%d", (int) (sizeof(void *)*8));}
^~~~
1 warning generated.
clang: warning: argument unused during compilation: '-s'
This warning is in the shell script that I used to compile the libraries. Could someone tell me what the -'s' flag is and how I can remove this warning?
Next warning:
warning: unknown warning option '-Wno-long-double'; did you mean '-Wno-long-long'? [-Wunknown-warning-option]
and the next one,
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: fortify.o has no symbols
clang: warning: argument unused during compilation: '-s'
Anyway to silence these warning?
Look at the manual of gcc for details of what each option should do.
AFAICT, clang not accepting those flags does not lead to any failure of the built executable.
Excerpt:
-s: Remove all symbol table and relocation information from the executable. (linker)
-Wno-long-double: Looks like someone wants to disable use of long double. Cannot find it for newest GCC. Chances are the code does not contain such anyway.

strerror_r causes error when compiling on SunOS (C Programming)

I have a C program which compiles and runs fine under Linux without any warnings, but when trying to compile it on SunOS, I get the following warning:
test.c: In function `my_function':
test.c:412: warning: implicit declaration of function `strerror_r'
Undefined first referenced
symbol in file
strerror_r /var/tmp/ccRiPoGl.o
ld: fatal: Symbol referencing errors. No output written to test
collect2: ld returned 1 exit status
make: *** [test] Error 1
Any ideas?
The "implicit declaration" warning is telling you that none of the headers you have #included have defined that function, and the "undefined symbol" warning is telling you that the function itself isn't defined in any of the libraries that you're linking in.
Taken together, this implies that C library you're compiling against doesn't provide the strerror_r function. You'll have to roll your own alternative.
For example, if you're using pthreads, you could do this:
int my_strerror_r(int errnum, char *buf, size_t buflen)
{
static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;
if (!buflen)
{
errno = ENOSPC;
return -1;
}
buf[0] = 0;
pthread_mutex_lock(&strerror_lock);
strncat(buf, strerror(errnum), buflen - 1);
pthread_mutex_unlock(&strerror_lock);
return 0;
}
It looks like strerror_r may not be available on that platform. I just checked on an old Solaris 2.8 box and strerror_r is not available.
It looks like you'll have to use strerror and deal with the occasional incorrect results due to the lack of thread safety.
Sounds like you need to give an extra hint to the linker to specify the library, it may not be in a standard path as is the case with Linux, if you know the name of the library, explicitly specify the library path as part of the CLI compiler when invoking gcc or equivalent under SunOS.
Here's an example of using a LIBS variable in a makefile.
LIBS = -L/usr/lib -L/usr/sys/lib -lsome_lib1 -lsome_lib2
Here's a line that is used to invoke the compiler in the makefile - notice the reference to the LIBS variable as I have shown in the above.
$(CC) -o $# $(FILES) $(LIBS) $(CFLAGS)
Hope this helps,
Best regards,
Tom.
Linux and SunOS are different operating systems and possibly have different implementations of the function you are using.
You might find the following article on POSIX compatibility by Dr. Bernstein at the University of Chicago at Illinois helpful:
http://cr.yp.to/docs/unixport.html
Good luck,
-bn

Resources