Xcode中Objective-C使用va_start触发默认参数提升未定义行为求助
Hey there! Nice job building your first Objective-C app—totally feel the learning curve here, no need to apologize at all 😊 Let's break down what's causing those errors and fix them up.
问题原因
The compiler errors are happening because of default argument promotions in C/C++ when using variadic functions. Types like int8_t (which is a typedef for signed char), char, and short get automatically promoted to int when passed as variable arguments. When you pass a type that gets promoted to va_start, it triggers undefined behavior—this is exactly what your error messages are pointing out.
修正后的代码
Here's a fixed version of your initializer that avoids those issues:
- (id)initWithBytes:(int)firstByte, ... { va_list args; va_start(args, firstByte); // Now using an int parameter, which matches promotion rules unsigned int length = 0; int8_t currentByte = (int8_t)firstByte; // Calculate total length of the byte sequence (stopping at -1) if (currentByte != -1) { length++; for (int arg = va_arg(args, int); arg != -1; arg = va_arg(args, int)) { length++; } } va_end(args); // Initialize the instance with the calculated length if ((self = [self initWithLength:length]) && length > 0) { va_list argsCopy; va_start(argsCopy, firstByte); int i = 0; _array[i++] = (int8_t)firstByte; // Populate the array with remaining bytes for (int arg = va_arg(argsCopy, int); arg != -1; arg = va_arg(argsCopy, int)) { _array[i++] = (int8_t)arg; } va_end(argsCopy); } return self; }
关键修改点说明
- Changed the first parameter type to
int: This aligns with the default argument promotion rule, sova_startno longer triggers undefined behavior. We just cast the value back toint8_twhen we need to store it. - Handled edge case for first byte = -1: If the first argument is
-1, we set length to 0 instead of looping, which prevents creating an empty or invalid array. - Used a separate
va_listfor population: Once you callva_endon ava_list, it's no longer usable. We declare a newva_list(argsCopy) to repopulate the array after calculating the length.
A quick side note: For Objective-C development, you might find it more idiomatic to use NSData or NSArray to pass byte sequences instead of variadic functions—this avoids these low-level C pitfalls entirely. But if you're working through learning variadic functions, the above fix should get you up and running!
内容的提问来源于stack exchange,提问作者petterandersson

