vararg stdarg with 64 bit values

Asked by Jeff Senn on 2017-11-28

I'm having trouble passing 'long long' or 'double' through a vararg function on a 32-bit ARM system raw hardware build.
Not only is the value wrong, but also following arg values.
Current downloaded binary build of the compiler 6.3.1
-march=armv7-a -mtune=cortex-a8 -mfpu=neon -ftree-vectorize -ffast-math -mfloat-abi=softfp -mcpu=cortex-a8

Can anyone verify it works for them?

#include <stdarg.h>

long vartest(char *foo, ...) {
  long long x;
  long y;
  va_list va;
  va_start(va, foo);
  x = va_arg(va, long long);
  y = va_arg(va, long);
  return y;

int test() {
  long long x = 0x300000002;
  long y = 0x7;
  long r = vartest("foo",x,y); //r will be incorrect
  return r;

Question information

English Edit question
GNU Arm Embedded Toolchain Edit question
No assignee Edit question
Solved by:
Jeff Senn
Last query:
Last reply:
Jeff Senn (jeffsenn) said : #1

(Not sure if I'm embarrassed or not at answering my own question)

Seems like my stack pointer was not initialized to be aligned with a double-word boundary.

The code generated by the compiler assumes (perhaps reasonably) that this is true - therefore a bit of code injected by va_arg (which aligns a double word pointer -- needlessly btw, because if va_arg didn't do it you're screwed anyway) is incorrect for this case.

Leaving here in case anyone else has a similar problem.