Date: Fri, 13 Feb 2026 20:36:09 +0100
Hi Halalaluyafail3,
On 2026-02-13T13:33:33-0500, Halalaluyafail3 wrote:
> > #define reproducible
>
> This violates:
>
> If the program defines a reserved identifier or standard attribute token
> described in 6.7.13.2 as a macro name, or removes (with #undef) any macro
> definition of an identifier in the first group listed previously or standard
> attribute token described in 6.7.13.2, the behavior is undefined.
Well, considering that the intention of such a program is triggering UB
by telling the compiler that a function is reproducible without it
really being so, I don't think it's a big problem.
Another approach would be to not include the header in its own TU:
// f.h
[[reproducible]] int f(void);
// f.c
int f(void)
{
static int i;
return i++;
}
>
> Section 6.4.2.1 Paragraph 9 ISO/IEC 9899:2024
>
> This does mean that being able to use __reproducible__ and other attribute names
> that both begin and end with two underscores is useless. Also:
>
> Conversely, if a definition that does not have the asserted property is accessed
> by a function declaration or a function pointer with a type that has the
> attribute, the behavior is undefined.
>
> Section 6.7.13.8.1 Paragraph 3 ISO/IEC 9899:2024
>
> So even ignoring the issue of defining reproducible being undefined, all users
> must equivalently define reproducible themselves to avoid undefined behavior.
>
> > + A definition of
> > + a function declared with the <b>reproducible</b> attribute
> > + shall not contain,
> > + anywhere in the tokens making up the function definition,
> > + a reference to a function
> > + declared without the <b>reproducible</b> attribute.
>
> Does this mean the following would be invalid:
>
> int foo();
> int(*bar()[[reproducible]])(){
> return foo;
> }
Hmmm, good catch. I think I could limit this to disallow the function
call operator on such functions, allowing anything else.
>
> Or even more innocuously:
>
> void baz()[[reproducible]]{
> int qux();
> }
And why would you want to declare a function that you can't use within
a reproducible function? I don't see this as a problem.
>
> Additionally, how would this work when considering functions which are later
> defined as reproducible:
>
> int a();
> int b()[[reproducible]]{
> return a();//appears invalid here
> }
> int a()[[reproducible]];//but becomes valid later
Don't do that, I guess. It's a diagnostic that you could easily fix by
moving the attribute earlier.
>
> int c();
> int d(){
> return c();//appears valid here
> }
> int d()[[reproducible]];//but becomes invalid later
Don't do that, I guess. IFNDR.
>
> Or even both together:
>
> int e();
> int f(){
> return e();//appears valid here
> }
> int f()[[reproducible]];//but becomes invalid later
> int e()[[reproducible]];//then becomes valid again
>
> Function pointers also do not seem to be included here:
>
> void g(void h())[[reproducible]]{
> h();//OK?
> }
Since you dereference the pointer to be able to call it, there's a
reference to a function. With explicit wording about the function call
operator, it would be more clear.
>
> A lot of the standard library does not use [[reproducible]] or [[unsequenced]]
> even if it should,
Then ask your vendor to use it.
> this would make a lot of code invalid even if it was probably
> relying on the implementation to not be malicious.
Or stupid.
> For example stdckdint.h,
> stdarg.h, offsetof, etc. If this is going to be a constraint then the use of
> these attributes should increase in the standard library to not break so much
> code.
Certainly.
>
> > [[reproducible]] is unnecessarily dangerous. The same or very
> > similar optimization goals could be achieved without a complete
> > and irresponsible disregard for safety.
>
> By the way, noreturn can also cause undefined behavior.
I'm aware. Half of the attributes cause UB. I started with this one
in part because it's the most obvious UB. I would continue with others.
> If this is about making
> undefined behavior harder to get then I think it would be worth including that
> too, for example requiring no return statements.
Agree.
> Possibly also requiring that
> control flow never reaches the end by requiring an infinite loop or another call
> to a noreturn function, or unreachable() to add the undefined behavior back.
Agree.
>
> > The committee is somehow acknowledging that attributes should
> > be as dreaded as casts?! Why would we standardize these
> > features in the first place?
>
> Similar attributes had already existed before in GCC and Clang at least. It was
> standardizing attributes that had already existed before.
Yeah, except that it probably wasn't the intention of GCC to leave them
without diagnostics; it was rather lack of time to implement the
diagnostics. I don't think GCC explicitly wanted a tool that makes it
so easy to trigger UB.
Have a lovely night!
Alex
On 2026-02-13T13:33:33-0500, Halalaluyafail3 wrote:
> > #define reproducible
>
> This violates:
>
> If the program defines a reserved identifier or standard attribute token
> described in 6.7.13.2 as a macro name, or removes (with #undef) any macro
> definition of an identifier in the first group listed previously or standard
> attribute token described in 6.7.13.2, the behavior is undefined.
Well, considering that the intention of such a program is triggering UB
by telling the compiler that a function is reproducible without it
really being so, I don't think it's a big problem.
Another approach would be to not include the header in its own TU:
// f.h
[[reproducible]] int f(void);
// f.c
int f(void)
{
static int i;
return i++;
}
>
> Section 6.4.2.1 Paragraph 9 ISO/IEC 9899:2024
>
> This does mean that being able to use __reproducible__ and other attribute names
> that both begin and end with two underscores is useless. Also:
>
> Conversely, if a definition that does not have the asserted property is accessed
> by a function declaration or a function pointer with a type that has the
> attribute, the behavior is undefined.
>
> Section 6.7.13.8.1 Paragraph 3 ISO/IEC 9899:2024
>
> So even ignoring the issue of defining reproducible being undefined, all users
> must equivalently define reproducible themselves to avoid undefined behavior.
>
> > + A definition of
> > + a function declared with the <b>reproducible</b> attribute
> > + shall not contain,
> > + anywhere in the tokens making up the function definition,
> > + a reference to a function
> > + declared without the <b>reproducible</b> attribute.
>
> Does this mean the following would be invalid:
>
> int foo();
> int(*bar()[[reproducible]])(){
> return foo;
> }
Hmmm, good catch. I think I could limit this to disallow the function
call operator on such functions, allowing anything else.
>
> Or even more innocuously:
>
> void baz()[[reproducible]]{
> int qux();
> }
And why would you want to declare a function that you can't use within
a reproducible function? I don't see this as a problem.
>
> Additionally, how would this work when considering functions which are later
> defined as reproducible:
>
> int a();
> int b()[[reproducible]]{
> return a();//appears invalid here
> }
> int a()[[reproducible]];//but becomes valid later
Don't do that, I guess. It's a diagnostic that you could easily fix by
moving the attribute earlier.
>
> int c();
> int d(){
> return c();//appears valid here
> }
> int d()[[reproducible]];//but becomes invalid later
Don't do that, I guess. IFNDR.
>
> Or even both together:
>
> int e();
> int f(){
> return e();//appears valid here
> }
> int f()[[reproducible]];//but becomes invalid later
> int e()[[reproducible]];//then becomes valid again
>
> Function pointers also do not seem to be included here:
>
> void g(void h())[[reproducible]]{
> h();//OK?
> }
Since you dereference the pointer to be able to call it, there's a
reference to a function. With explicit wording about the function call
operator, it would be more clear.
>
> A lot of the standard library does not use [[reproducible]] or [[unsequenced]]
> even if it should,
Then ask your vendor to use it.
> this would make a lot of code invalid even if it was probably
> relying on the implementation to not be malicious.
Or stupid.
> For example stdckdint.h,
> stdarg.h, offsetof, etc. If this is going to be a constraint then the use of
> these attributes should increase in the standard library to not break so much
> code.
Certainly.
>
> > [[reproducible]] is unnecessarily dangerous. The same or very
> > similar optimization goals could be achieved without a complete
> > and irresponsible disregard for safety.
>
> By the way, noreturn can also cause undefined behavior.
I'm aware. Half of the attributes cause UB. I started with this one
in part because it's the most obvious UB. I would continue with others.
> If this is about making
> undefined behavior harder to get then I think it would be worth including that
> too, for example requiring no return statements.
Agree.
> Possibly also requiring that
> control flow never reaches the end by requiring an infinite loop or another call
> to a noreturn function, or unreachable() to add the undefined behavior back.
Agree.
>
> > The committee is somehow acknowledging that attributes should
> > be as dreaded as casts?! Why would we standardize these
> > features in the first place?
>
> Similar attributes had already existed before in GCC and Clang at least. It was
> standardizing attributes that had already existed before.
Yeah, except that it probably wasn't the intention of GCC to leave them
without diagnostics; it was rather lack of time to implement the
diagnostics. I don't think GCC explicitly wanted a tool that makes it
so easy to trigger UB.
Have a lovely night!
Alex
-- <https://www.alejandro-colomar.es>
Received on 2026-02-13 19:36:20
