Is there a way to detect ABI in C/C++ at compile time? I know there are macros for OS and CPU architecture. Are there similar macros (or some other way) for ABI?
-
6C is not C++ is not C, please select only one language because your question is too broad. – Stargateur Nov 05 '17 at 09:25
-
3Why do you ask? What is your concrete use case? What platform, compiler, for what software? Please **edit your question** to improve it. It should give a lot more details and be much longer. – Basile Starynkevitch Nov 05 '17 at 09:30
-
@Stargateur Lol, how is the question to broad? Most macros (e.g. os and cpu architecture) are shared between C and C++ compilers. Making the distinction in my case is completely artifical. – freakish Nov 05 '17 at 10:34
-
1@BasileStarynkevitch I have a concrete case which is really irrelevant. If I ask about ABI then the answer should be compiler independent (it's not like different compilers use different ABI on the same platform). I'm looking for a cross-platform (or per major platforms) solution. – freakish Nov 05 '17 at 10:38
-
1@freakish, to see how clang does it, you may start from the latest [TargetInfo.h](https://clang.llvm.org/doxygen/include_2clang_2Basic_2TargetInfo_8h_source.html) source at trunk and follow the rabbit to find which macros are defined when ... as far as I can see, the ABI is always just a piece of the puzzle, so it's not suprising there's no 'global' macro for that. – Massimiliano Janes Nov 05 '17 at 10:47
-
2The concrete case is relevant and is compiler dependent in general. Many compilers can generate code for a variety of ABIs. In general the C or C++ code you are writing should not depend upon a particular ABI, but they are some rare exceptions. – Basile Starynkevitch Nov 05 '17 at 10:49
-
@BasileStarynkevitch yes, but not on one platform. I mean there is always a default abi they use (you dont set it manually before you compile). And that is either detected or manually set for the compiled compiler (if you know what i mean). – freakish Nov 05 '17 at 10:53
-
1My Debian system has several ABIs. There is no a *default* one. Indeed, without additional options, the `gcc` command is using one which is very *common* (but not a default). – Basile Starynkevitch Nov 05 '17 at 11:02
-
So the unedited question is very poorly asked (still don't mention the use case, probably some compiler if I guess it well). I downvoted it and voted to close it. See [this metaquestion](https://meta.stackoverflow.com/q/358255/841108). The OP should have improved his question !! – Basile Starynkevitch Nov 05 '17 at 11:12
-
@BasileStarynkevitch How is the question poorly asked? Would it change anything adding "I'm writing a compiler"? How is that relevant to the question? I'm not asking about writing a compiler. I'm specifically asking how to detect abi, nothing else. – freakish Nov 05 '17 at 11:17
-
See how much edits I needed to answer your question. If you have told from start that you are writing a compiler (and gave your actual kind of language and target processor and ABI), I could have answered much faster. And the real point is that you don't need to only detect the ABI. You need to choose one and follow it. If you follow my latest hints (use LLVM or GCCJIT or emit C code), you don't even need to detect the ABI. So you have an [XY problem](http://xyproblem.info/) – Basile Starynkevitch Nov 05 '17 at 11:18
-
1Your question illustrates what I strongly believe. A lot of questions are lacking motivation, and most people don't put enough effort and time in asking them. I'm still hoping that the quality of questions on SO will increase (or at least stop decreasing, as I observed). Motivation and context is very important. – Basile Starynkevitch Nov 05 '17 at 11:20
-
So yes, if you have stated from start that you are e.g. "writing a compiler for ARM/Linux ABI" that would have changed your question a big lot (and I would have upvoted it). As I explained, you don't really need to detect the ABI. – Basile Starynkevitch Nov 05 '17 at 11:26
-
So please, **next time, write a better question,** with a few sentences for *context and motivation*. – Basile Starynkevitch Nov 05 '17 at 11:32
-
@BasileStarynkevitch this is not xy problem. This is something you arbitrarly stated now. I need that info. You dont need to know why. Your answer might be helpful and i am grateful but dont tell me what i need. – freakish Nov 05 '17 at 11:34
-
1You are wrong, and you forget to consider the time you needed to ask your bad question, and the time I spent improving mine till it becomes good. Since a question is more often read than written people should spend more efforts in writing them (than in answering them). And a better asked question is more easy to find (later, by people Googling this SO). As a courtesy for readers, spend more efforts in writing your questions. You write questions for others (not only for you) – Basile Starynkevitch Nov 05 '17 at 11:35
-
The point is to avoid SO becoming a junk of bad questions. 5 years ago it was better. We need it to improve. You are implicitly expecting people to read in your mind. That can't work with just a web interface (non-verbal communication don't exist on the web). – Basile Starynkevitch Nov 05 '17 at 11:38
-
You yourself say that you want a compiler independent solution. So all you can rely on is the standards. __Yet__ you claim that the disctintion here between C and C++ is artificial? – Ajay Brahmakshatriya Nov 05 '17 at 12:05
-
*it's not like different compilers use different ABI on the same platform* yes they very much do. Even two different functions in the same file can use different ABIs. – Ajay Brahmakshatriya Nov 05 '17 at 12:07
-
@AjayBrahmakshatriya Yes, I meant the standard. The C++ and C standards are very much alike in the standard macros context though. Also it doesnt matter what a function does inside. Calling convention (the part of ABI im mostly interested in) is for communication between binaries. I still don't see how one OS can support different calling conventions without stuff breaking apart. But that's obviously the knowledge I'm missing. – freakish Nov 05 '17 at 12:19
-
1@BasileStarynkevitch I don't expect anyone to read in my mind. The question is clearly stated (you even contradict yourself since you gave me an answer). It is you who actually tries to tell me what I need. I don't see the point of discussing this anymore. – freakish Nov 05 '17 at 12:22
-
1@freakish yes the OS can support different ABIs. For example how the exceptions are handled. If you are only interested about the calling conventions, those can be different too as long as both the caller and callee agree. Interrupt handlers for instance usually follow different calling conventions. Even for normal functions, OS need not support different calling conventions. If the functions are private they can use any calling convention. – Ajay Brahmakshatriya Nov 05 '17 at 12:29
-
@Stargateur im not interested in pointless ranting at meta. Good for you. – freakish Nov 06 '17 at 08:24
1 Answers
The notion of ABI is not known to standard specification like C11 or C++14. It is an implementation thing.
You could on Linux use feature_test_macros(7).
You could consider improving your build procedure (e.g. your Makefile
, etc...). You might run some shell script detecting features (like autoconf generated configure
scripts do). Notice that some C or C++ code (e.g. header files, etc...) might be generated at build time (for examples: by bison, moc, rpcgen, swig, ...), perhaps by your own utilities or scripts. Use a good enough build automation tool (with care, GNU make and ninja are able to deal with generated C++ or C code and manage their generation and the dependencies).
Don't confuse compilation with build; the compilation commands running a compiler are just parts of the build process.
Some platforms accept several ABIs. E.g. my Linux/Debian/Sid/x86-64 desktop with a Linux 4.13 kernel can run x86 32 bits ELF executable, x86-64 64 bits ELF, probably some old a.out
format from the 1980s, and also x32 ABI. With binfmt_misc I can add even more ABIs. See x86 psABI for a list of several ABI documentations.
BTW, the current trend is to try writing portable code. Perhaps using frameworks like Qt or POCO or Glib (and many others) could hide the ABI details to your application.
In some cases, libffi might be helpful too.
In general, once you know your OS and your architecture, you can practically -most of the time- deduce the ABI.
If you really want your ABI, then a possible Linux specific way might be to run file(1) on the current executable. I don't recommend doing that, but you could try (using proc(5) to get the executable):
/// return a heap allocated string describing the ABI of current executable
//// I don't recommend using this
const char*getmyabi(void) {
char mycmdname[80];
int sz = snprintf(mycmdname, sizeof(mycmdname),
"/usr/bin/file -L /proc/%d/exe",
getpid());
assert (sz < (int) sizeof(mycmdname));
FILE*f = popen(mycmdname, "r");
if (!f) {
perror(mycmdname); exit(EXIT_FAILURE);
};
char* restr = NULL;
size_t siz = 0;
getline(&restr, &siz, f);
if (pclose(f)) { perror("pclose"); exit(EXIT_FAILURE); };
return restr;
} // end of getmyabi
/// the code above in untested
You could get a string like:
"ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked,"
" interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,"
"BuildID[sha1]=deca50aa4d3df4d57bacc464aa1e8790449ebf8e, stripped"
then you need to parse that. You could also want to parse the output of ldd(1) or of objdump(1) on your executable, your ELF interpreter ld-linux(8), etc.... (or use some ELF parsing library for that).
I don't know how useful is that getmyabi
function. I don't know what precise output is file
giving (in all weird cases of various ABIs). I leave you to test it (be sure to compile your test program with all the ABIs installed on your system, so gcc -m32
, gcc -m64
, gcc -mx32
, etc....); if possible test that on some non x86 Linux system.
If you just need to get your ABI at build time, consider compiling some hello-world executable, then run file
(and ldd
) on it. Have appropriate build rules (Makefile
rules) doing that and parsing the output of those file
and ldd
commands.
(I am surprised of your question; what kind of application needs to know the ABI; most software needing that are compilers...; a strong dependency on a precise ABI might be the symptom of undefined behavior.)
Perhaps the hints given here might apply to your case (just a blind guess).
If you are writing some compiler, consider generating some C code in it then use some existing C compiler on that generated C code, or use a good JIT compilation library like LIBGCCJIT or LLVM. They would take care of the ABI specific aspects (and more importantly of low-level optimizations and code generation).
If you are writing a compiler alone and don't want to use external tools, you should in practice restrict yourself to one or a few ABIs and platforms. Life is short.
PS. I am not sure at all that ABI has a precise meaning. It is more a specification document than a defined feature of some system (or some executable). IIUC, the ABI specification did evolve (probably was not exactly the same 15 years ago).

- 223,805
- 18
- 296
- 547
-
`most software needing that are compilers` Well, you've answered your own question. :) Thanks for the answer, I'm going to read all the linked articles. – freakish Nov 05 '17 at 10:32
-
1Well if you're dealing with e.g. the internal language exception mechanisms (like the [`__cxxabi`](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html]) stuff), to perhaps set an intermediate level with other platforms/language, you may have such need, and I'm sorry for you. – edmz Nov 05 '17 at 11:10
-
1[Life is short](https://gamedev.stackexchange.com/questions/121378/what-advantage-do-opengl-sfml-and-sdl-have-over-software-rendering/121405#121405) – edmz Nov 05 '17 at 11:13