Been working on my own language for some time now and I've been implementing implicit and explicit casts. Went back to check what happens when invoking them. Everything went well, until I tried to invoke a cast from a double. Passing doubles to functions for some reason results in clang giving me an error when linking the obj file to the cpp file that invokes it, namely:"clang.exe: error: linker command failed with exit code 1143 (use -v to see invocation)program.obj : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0x5"
I've then noticed this also happens with floats, but does not occur with integers and the likes. I've written a short function (takes a double by value and returns it) to check whether the problem was related to parameters of types float/double. The error only occurs when invoking the function, when defining the function but not invoking it, everything functioned properly. I've also tried to simply store a double literal in memory (alloca) and that worked as well, so the problem has to be with actually passing the argument to the function.
Simple LLVM IR for a function that takes a double by value and returns it, then being invoked from main (main is names _mainCRTStartup as to not confuse it with the symbol for the main function from the cpp file that then invokes it (extern "C"))
Thanks for any help in advance! :D
First of all, I have read this post Why do you need an explicit `-lm` compiler option & this gcc: why is the -lm flag needed to link the math library?. I wanna know why It doesn't happen in case of constants (when I say constants, I mean random floats/doubles)? If you're confused, call it floating-point literals.
Why do we have to use -lm to tell the linker to use math.h functions only when using variables as parameters but not constants? If I use sqrt(N)(N is some number), it compiles fine without any errors but when I pass some variable, let's say sqrt(var), it doesn't. It says:
/usr/bin/ld: /tmp/cc5P9o72.o: in function `main':
sq.c:(.text+0x1b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
It should behave the same all the time (I think so, but I am wrong, of-course) as I am using the same function from the same library. Either its variable or constant. I first thought its some kind of compiler optimization (if it's the same value every time, why not calculate it while compiling by some other way, i.e not using the library, as it's not working) but it's doesn't work even if I pass some variable that has a fixed value from beginning to the end. So, I was wrong there. What is actually happening here?
Following is the snippet I tried:
#include <stdio.h>
#include <math.h>
int main () {
float a=9;
printf("%f",sqrt(a));
return 0;
}
It is very simple. When you pass the constants many compilers will evaluate it (in such a trivial example when the result is not float inaccuracies and implementation differences prone) compile time without calling the math.h functions.
Even if you do not pass the constants values and compile it with no math error checks and fast math, the compiler will generate the direct float machine code instructions without calling the library ones
Before asking check the generated code for example using the godbolt.org, and usually it will answer all of your questions
In Debian 8's source code /source/procps-3.3.9/lib/fileutils.c line 38 is:
char const *write_error = _("write error");
I am confused about the _("write error") part. Google showed that result on variable naming convention or library reserved names, but nothing about when _ was on the right side of = and before a () quoted string.
I also put this line into a simplest test program as only useful line then had compilation failed saying:
test.c:5:20: warning: implicit declaration of function ‘_’ [-Wimplicit-function-declaration]
char const *str = _("test string");
^
test.c:5:20: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
/tmp/cczQpqTh.o: In function `main':
test.c:(.text+0x15): undefined reference to `_'
collect2: error: ld returned 1 exit status
Does anyone know what _(" ") format means?
This is the standard way to mark up strings for translation using GNU gettext, a free software translation tool.
The _() macro is found by an external tool which extracts the text to make it translatable, as well as (at run-time) do look-ups to replace the literal with the necessary translation.
There is nothing special about the name _, it's just a very short but perfectly valid C identifier. Perhaps it's a bit iffy to begin a public symbol with an underscore, I'm not sure right now.
The error you're getting is because your test program very likely fails to include the <libintl.h> header (part of gettext, of course) which declares this macro. Thus you get the normal "undefined reference" error, as expected.
So I am trying to convert a C program that uses standard libraries to a standalone application (it is an assignment). This involves writing simple functions for printf, malloc, free and etc. While working on this, I came across a problem of converting fflush(stdout) because stdout is included in stdio.h and must be replaced with something else.
Naturally, I looked at the macro in stdio.h which looked like:
#define stdout (__iob[1])
I used this macro declaration in my C file, removed the stdio.h header, and tried to compile it, but it gave an error __iob is undeclared. When I looked at the source file more in detail, there was a data structure:
extern struct __file *__iob[];
With this included, when compiled, it gives another error below and I am not sure what to make of this:
/tmp/ccOTmFBR.o: In function `func1':
program.c:(.text+0x46): undefined reference to `__iob'
/tmp/ccOTmFBR.o: In function `func2':
program.c:(.text+0xff): undefined reference to `__iob'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
My question is basically what would be the simplest way to replace fflush(stdout) in a C program without using the stdio.h.
This code compiles, but no surprises, it fails while linking (no main found):
Listing 1:
void main();
Link error: \mingw\lib\libmingw32.a(main.o):main.c:(.text+0x106) undefined reference to _WinMain#16'
But, the code below compiles and links fine, with a warning:
Listing 2:
void (*main)();
warning: 'main' is usually a function
Questions:
In listing 1, linker should have
complained for missing "main". Why
is it looking for _WinMain#16?
The executable generated from
listing 2 simply crashes. What is
the reason?
Thanks for your time.
True, main doesn't need to be a function. This has been exploited in some obfuscated programs that contain binary program code in an array called main.
The return type of main() must be int (not void). If the linker is looking for WinMain, it thinks that you have a GUI application.
In most C compilation systems, there is no type information associated with symbols that are linked. You could declare main as e.g.:
char main[10];
and the linker would be perfectly happy. As you noted, the program would probably crash, uless you cleverly initialized the contents of the array.
Your first example doesn't define main, it just declares it, hence the linker error.
The second example defines main, but incorrectly.
Case 1. is Windows-specific - the compiler probably generates _WinMain symbol when main is properly defined.
Case 2. - you have a pointer, but as static variable it's initialized to zero, thus the crash.
On Windows platforms the program's main unit is WinMain if you don't set the program up as a console app. The "#16" means it is expecting 16 bytes of parameters. So the linker would be quite happy with you as long as you give it a function named WinMain with 16 bytes of parameters.
If you wanted a console app, this is your indication that you messed something up.
You declared a pointer-to-function named main, and the linker warned you that this wouldn't work.
The _WinMain message has to do with how Windows programs work. Below the level of the C runtime, a Windows executable has a WinMain.
Try redefining it as int main(int argc, char *argv[])
What you have is a linker error. The linker expects to find a function with that "signature" - not void with no parameters
See http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html etc
In listing 1, you are saying "There's a main() defined elsewhere in my code --- I promise!". Which is why it compiles. But you are lying there, which is why the link fails. The reason you get the missing WinMain16 error, is because the standard libraries (for Microsoft compiler) contain a definition for main(), which calls WinMain(). In a Win32 program, you'd define WinMain() and the linker would use the library version of main() to call WinMain().
In Listing 2, you have a symbol called main defined, so both the compiler & the linker are happy, but the startup code will try to call the function that's at location "main", and discover that there's really not a function there, and crash.
1.) An (compiler/platform) dependent function is called before code in main is executed and hence your behavior(_init in case of linux/glibc).
2) The code crash in 2nd case is justified as the system is unable to access the contents of the symbol main as a function which actually is a function pointer pointing to arbitrary location.