title: Is it possible to use explicit register variables in GCC with C++17?
body: <p>I am using <a href="https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables" rel="noreferrer">explicit register variables</a> to pass parameters to a raw Linux syscall using registers that don't have <a href="https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html" rel="noreferrer">machine-specific constraints</a> (such as r8, r9, r10 on x86_64) as suggested <a href="https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands" rel="noreferrer">here</a>.</p>
  
  <pre><code>#include &lt;asm/unistd.h&gt;
  
  #ifdef __i386__
  #define _syscallOper "int $0x80"
  #define _syscallNumReg "eax"
  #define _syscallRetReg "eax"
  #define _syscallReg1 "ebx"
  #define _syscallReg2 "ecx"
  #define _syscallReg3 "edx"
  #define _syscallReg4 "esi"
  #define _syscallReg5 "edi"
  #define _syscallReg6 "ebp"
  #define _syscallClob
  #else
  #define _syscallOper "syscall"
  #define _syscallNumReg "rax"
  #define _syscallRetReg "rax"
  #define _syscallReg1 "rdi"
  #define _syscallReg2 "rsi"
  #define _syscallReg3 "rdx"
  #define _syscallReg4 "r10"
  #define _syscallReg5 "r8"
  #define _syscallReg6 "r9"
  #define _syscallClob "rcx", "r11"
  #endif
  
  template &lt;typename Ret = long, typename T1&gt;
  Ret syscall(long num, T1 arg1)
  {
      register long _num __asm__(_syscallNumReg) = num;
      register T1 _arg1 __asm__(_syscallReg1) = arg1;
      register Ret _ret __asm__(_syscallRetReg);
      __asm__ __volatile__(_syscallOper
          : "=r"(_ret)
          : "r"(_num), "r"(_arg1)
          : _syscallClob);
      return _ret;
  }
  
  extern "C" void _start()
  {
      syscall(__NR_exit, 0);
  }
  </code></pre>
  
  <p>However this feature requires the use of <code>register</code> keyword which was deprecated in C++11 and removed in C++17. So when I compile this code with GCC 7 (<code>-std=c++17 -nostdlib</code>) it gives me a warning:</p>
  
  <pre><code>ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
  </code></pre>
  
  <p>and it seems to ignore the register allocation and the program segfaults because syscall wasn't called properly. This code however compiles and works fine in Clang 6. <em>Note: I actually have 6 syscall functions (up to 6 arguments) but only 1-argument version is shown here for the sake of minimal example.</em> </p>
  
  <p>I realize that <code>register</code> keyword by itself wasn't really useful that's why it was removed, but this specific use case seems like an exception to me so it seems unreasonable to remove compiler support for it as well.</p>
  
  <p>I also realize that this use case is compiler-specific (i.e. non-standard), so my question is about compiler support rather then removal from the standard.</p>