Issue 1089: offsetof and va_arg handling of commas outside of parentheses

Authors: Jay Ghiron
Date: 2026-06-26
Submitted against: C23
Status: Open

offsetof contains wording to forbid the following:

#include<stddef.h>
int main(){
offsetof(struct{int x,y;},y);
}

offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the subobject (designated by member-designator), from the beginning of any object of type type. The type and member designator shall be such that given

static type t;

then the expression &(t.member-designator) evaluates to an address constant. If the specified type name contains a comma not between matching parentheses or if the specified member is a bit-field, the behavior is undefined.

(C23 7.21 "Common definitions <stddef.h>" paragraph 4.)

However, there does not appear to be any equivalent wording for va_arg:

#include<stdarg.h>
void f(...){
va_list v;
va_start(v);
va_arg(v,struct{int a,b;});/* OK? */
va_arg(v,char(*)[0?1,2:3]);/* OK? */
va_arg(v,char(*)[(constexpr int){1,}]);/* OK? */
va_arg(v,int[[,]]);/* OK? */
va_end(v);
}

And offsetof does not have wording to forbid commas outside of parentheses in the member-designator:

#include<stddef.h>
int main(){
struct S{int z[4];};
offsetof(struct S,z[0?1,2:3]);/* OK? */
offsetof(struct S,z[(constexpr int){1,}]);/* OK? */
}

Existing implementations reject both of these uses just like commas outside of parentheses in the type of offsetof. I assume the intent is to not allow these uses. A correction should consider that macros can expand to include commas outside of parentheses as well:

#include<stdarg.h>
#define T int[[,]]
void g(...){
va_list w;
va_start(w);
va_arg(w,T);
va_end(w);
}

This would break with a definition of va_arg such as:

#define __va_arg(list,type)/*...*/
#define va_arg(list,type)__va_arg(list,type)

Since T will already be expanded by the time __va_arg begins expansion. It may also be useful to add wording that clearly forbids expressions from containing commas outside of parentheses, for any standard library macro (other than assert). This has always been implied, but does not actually appear to be stated.