(deleted)
//value = va_arg(args, uint8_t) ; // UNCOMMENTING CAUSES APPARENT HANG
I’ve not tried it, but from an example I looked at, you may have to do this:
value = (uint8_t) va_arg(args, uint16_t) ; // need a cast here since va_arg only takes fully promoted types
C promotes byte values to int values. If the function you are calling explicitly takes a byte, then in knows to only put a byte onto the stack. If it's varargs, then its going to put a 2-byte int. So any call that has a byte fails, except those ones where the byte is the last value - eg "421". In this case, the compiler still puts a 4,2,2 on the stack, but because the processor is little-endian, the first byte of that final two-byte value is the EF you expect.
(deleted)
there are no bugs in 50 years old code. only 'features'
*fmt++;
Perhaps you meant:
fmt++;
The code, as written, generates a pile of compiler warnings. Here it is with the warnings corrected and it produces results exactly as expected. I changed the data so the different sizes of variable had different data. That makes it easier to see that the data was being fetched from the right variable.
//#include <stdarg.h>
//#include <stdio.h>
void setup()
{
Serial.begin(115200);
test("421", 0x44444444, 0x2222, 0x11); // AS EXPECTED
test("222", (uint16_t)0x2222, (uint16_t)0x2222, (uint16_t)0x2222); // AS EXPECTED
test("444", (uint32_t)0x44444444, (uint32_t)0x44444444, (uint32_t)0x44444444); // AS EXPECTED
test("111", 0x11, 0x11, 0x11); // NOT AS EXPECTED
test("124", 0x11, 0x2222, 0x44444444); // NOT AS EXPECTED
test("412", 0x44444444, 0x11, 0x2222); // NOT AS EXPECTED
test("111", (uint8_t)0x11, (uint8_t)0x11, (uint8_t)0x11); // NOT AS EXPECTED
test("214", (uint16_t)0x2222, (uint8_t)0x11, (uint32_t)0x44444444); // NOT AS EXPECTED
test("412", (uint32_t)0x44444444, (uint8_t)0x11, (uint16_t)0x2222); // NOT AS EXPECTED
test("142", (uint8_t)0x11, (uint32_t)0x44444444, (uint16_t)0x2222); // NOT AS EXPECTED
}
void loop()
{
}
void test(const char *fmt, ...)
{
va_list args;
uint32_t value = 0x99999999;
Serial.print(fmt);
Serial.print(": ");
va_start(args, fmt);
while (*fmt != '\0')
{
switch (*fmt)
{
case '4':
value = va_arg(args, uint32_t);
break;
case '2':
value = va_arg(args, uint16_t);
break;
case '1':
value = (byte) va_arg(args, uint16_t);
break;
}
Serial.print("<"); Serial.print(value, HEX); Serial.print(">");
fmt++;
}
va_end(args);
Serial.println();
}
Output:
421: <44444444><2222><11>
222: <2222><2222><2222>
444: <44444444><44444444><44444444>
111: <11><11><11>
124: <11><2222><44444444>
412: <44444444><11><2222>
111: <11><11><11>
214: <2222><11><44444444>
412: <44444444><11><2222>
142: <11><44444444><2222>
(deleted)
(deleted)
you have to activate under file -preferences
show verbose output during compilation and compiler-warning set to all to see all error-messages
best regards Stefan
sparky961:
Perhaps, but it does work as I wrote it. Blame C.
It will work but it generates a warning message because you fetch a byte but don't use it.
/Users/john/Documents/Arduino/sketch_dec12a/sketch_dec12a.ino: In function 'void test(const char*, ...)':
/Users/john/Documents/Arduino/sketch_dec12a/sketch_dec12a.ino:69:5: warning: value computed is not used [-Wunused-value]
*fmt++;
^~~~~~
(deleted)
(deleted)
(deleted)