How is stdarg Provided in the C++ Runtime

165 views Asked by At

Background:

While setting up YouCompleteMe compile arguments for a standalone GCC + sysroot for aarch64, I went spelunking in the standard C++ system includes and found this little gem:

[sysroot]/usr/include/c++/11.2.0/cstdarg

#include <stdarg.h>

Which points at

[sysroot]/usr/include/c++/11.2.0/tr1/stdarg.h

#include <tr1/cstdarg>

Which, itself, points at

[sysroot]/usr/include/c++/11.2.0/tr1/cstdarg

#include <cstdarg>

Thereby looping us back to the beginning. The loop is ultimately broken by some #ifdef's but, ultimately, none of these files really defines anything substantial.

Since these three files all really just include other files, this is causing clangd (YCM's back-end compile server) to eventually parse

namespace std
{
  using ::va_list;
} // namespace std

from [sysroot]/usr/include/c++/11.2.0/cstdarg and then emit:

No member named 'va_list' in the global namespace

I double checked my standard system headers and they are essentially identical so this isn't just limited to my cross toolchain.

Questions:

  1. Where is va_list ultimately defined for C++?
  2. What arguments would I need to feed to clangd to resolve this?
  3. What is the purpose of defining system headers like this?

Reference:

The relevant compile arguments are:

'-xc++',
'-std=gnu++17',
'-stdlib=libc++',
'-nostdinc',
'-isystem', SYSROOT_AARCH64 + '/usr/include',
'-isystem', SYSROOT_AARCH64 + '/usr/include/linux',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0/tr1',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0/aarch64-poky-linux',

Comment Responses:

@PasserBy: Where are you seeing that? The only stdarg.h I have is under c++/11.2.0/tr1 (see comment response to teapot418 below) and this does not have any typedefs in it. The total content of this file (minus comments) is:

#ifndef _TR1_STDARG_H
#define _TR1_STDARG_H 1

#include <tr1/cstdarg>

#endif

This matches my host system's stdarg.h so I don't think this is a failing of the toolchain.

@Lundin: I am not using this but it looks like <string> eventually includes <cstdarg> which causes clangd errors.

@teapot418: I had considered this when I noticed that other headers were included as <tr1/foo>. The problem, though, is that removing tr1 as an include directory causes stdarg.h to not be found at all. A simple find reveals:

$ find /path/to/sysroot/ -name stdarg.h
/path/to/sysroot/usr/include/c++/11.2.0/tr1/stdarg.h

This is strange to me as I would have expected to find the C version of stdarg.h somewhere like [sysroot]/usr/include. I would be wrong, though, as comparing to my host system yields the same result:

$ find /usr/include/ -name stdarg.h
/usr/include/c++/12/tr1/stdarg.h

Is there some other shenanigans going on here that I am missing?

@KamilCuk: See below. One thing I notice is that the pats are being included from .../sysroots/x86_64-pokysdk-linux/... while I was primarily using paths from .../sysroots/aarch64-poky-linux/.... Yocto generates both of these as part of the SDK and, I admit, I don't fully appreciate the difference between the two. I would have expected all relevant headers to be in the aarch64-poky-linux but, clearly, this assumption is false.

aarch64-poky-linux-gcc -E -xc - <<<'#include <stdarg.h>'
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"
# 1 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 1 3 4
# 40 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4

# 40 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 99 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4
typedef __gnuc_va_list va_list;
# 2 "<stdin>" 2
0

There are 0 answers