-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What does -fno-common actually do? #324
Comments
That was with -fpie, with -fno-pie even the compiled code is the same. |
I have a feeling this option is unnecessary since http://sourceware-org.1504.n7.nabble.com/PATCH-0-5-Add-support-for-R-386-GOT32X-R-X86-64-REX-GOTPCRELX-td352660.html |
i was tempted to add -fno-common to my cflags mix , but really what it does ? |
It's for targets where it is beneficial. Really, I want GentooLTO running anywhere Gentoo does :) I know this has impact on at least certain ARM architectures |
Also: |
@InBetweenNames Thanks that is an interesting blog. I'm finding it hard to understand what the semantics are and why it does certain things: But the code on x86_32 is different: With -fno-common the last 4 instructions change to (it loads the GOT into But I don't understand why it couldn't have generated the same code in the -fcommon case. In 64-bit it assumed that both a and b were addressable relative to If I add -fPIC, the 32-bit code changes to the -fcommon variant for both. For 64-bit the code changes, again to the same in both cases, to |
I'm not entirely sure myself -- my first guess is that the codegen part of the compiler and the linker have historically been separate, so if the compiler needed any "link time" features, such as resolving tentative variable definitions in C, it would need to rely on the linker to do that and generate the definition. So, the codegen part of the compiler would have to assume the worst case scenario, which is that the definition is resolved outside of the TU. But I mean, this is just a guess and I'm probably wrong about that haha. |
Playing around with it, I notice at least one subtle case where you can silently get the wrong result. If a global variable is declared as: |
More info in Common-Variable-Attributes
|
Yeah I've seen that but trying to understand how it actually impacts code generation. At least on x86_64 it doesn't seem to change anything. |
It seems to make a difference on ARM architectures. Notably, the flag does break the C standard a bit, but not in a way that would result in incorrect codegen -- just a multiple definition error at compile time. |
The GCC doc says:
But is x86 actually one of them?
On x86_64 I see zero difference in the code generated. On 32-bit, there is a difference in the code generated by the compiler, but after linking, the two look identical.
On 32-bit the compiler generates
movl x@GOT(%eax), %eax
without -fno-common, vs
leal x@GOTOFF(%eax), %eax
but the linker seems to convert the mov into lea.
The text was updated successfully, but these errors were encountered: