Author Topic: C functions with "volatile" return types - what does it mean?  (Read 17774 times)

0 Members and 3 Guests are viewing this topic.

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4832
  • Country: us
Re: C functions with "volatile" return types - what does it mean?
« Reply #75 on: December 05, 2025, 01:23:52 am »
I wonder actually why x = a + a++; must be stringently considered undefined behavior, and not just unspecified behavior like subexpression or argument evaluation order?

I think honestly it was just convenience, and that the number of possibilities adds up too quickly.  Function calls provide a sequence point.  In my example with a() + b(), the functions a() and b() can execute in either order, but they can't be intermingled. The standard could try to make a specific claim about the possible orderings, but it's easier to just say its UB.  Remember, a lot of these things were defined before compilers got super aggressive about exploiting UB, and they weren't necessarily thinking about what could go wrong, they were just trying to avoid specifying things that didn't need to be specified.  I think there is a good chance C++ will change this from UB in the future, similar to how they already did for uninitialized variables.
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #76 on: December 05, 2025, 05:04:36 am »
I wonder actually why x = a + a++; must be stringently considered undefined behavior, and not just unspecified behavior like subexpression or argument evaluation order?
Nothing must be left undefined. The language designer is always allowed to put constraints on whatever piece of code they wish or even remove an uncomfortable feature. Python is a good example. First, it avoided the problem altogether by not having post- and pre-increment operators. PEP 572 introduced the possibility of writing something equivalent, but at the same time the order of evaluation is constrained and x = a + (a := a + 1) remains well-defined (6.16 and 6.17, together with not allowing += in := expressions).

However, mending each and every single gap in definitions faces both diminishing returns and rising costs. So naturally some areas are left undefined. It’s putting more constraints on the execution environment, just to perfect a piece of code of academic interest.

« Last Edit: December 05, 2025, 05:12:08 am by golden_labels »
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline westfwTopic starter

  • Super Contributor
  • ***
  • Posts: 4640
  • Country: us
Re: C functions with "volatile" return types - what does it mean?
« Reply #77 on: December 05, 2025, 10:02:53 am »
I feel like some "language purists" have decided that certain constructs that they "don't like" are undefined behavior, when they ought to be allowed.  Type punning, for instance, seems to be UB mainly to allow better optimization, but that seems like a poor excuse.
The alternatives ("do a memcpy and we'll probably optimize it away") seem much uglier, less obvious, and no more portable.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #78 on: December 05, 2025, 10:23:10 am »
Type punning, for instance, seems to be UB mainly to allow better optimization, but that seems like a poor excuse.

IMHO it is a poor excuse. Many aspects of C stem from that plus the desire not to break old code.

Compiler writers add lots of compiler flags to allow/detect/warn a multitude of such things, and they vary over time and between compilers. They change the correctness of a program to such an extent that they ought to be regarded as part of the language.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: C functions with "volatile" return types - what does it mean?
« Reply #79 on: December 05, 2025, 01:33:10 pm »
Type punning, for instance, seems to be UB
It is not UB if you do it via an union since C99; see 6.5.2.3p3 and footnote 82.  (Some language lawyers like to point out that footnotes are not normative, but the footnote describes clearly how type punning through an union should work by simply reinterpreting the storage pattern.)

That is, to get the unsigned integer bit pattern corresponding to a float variable or vice versa, you can use
Code: [Select]
static inline uint32_t float_to_bits(const float f) {
    const union {
        float f32;
        uint32_t  u32;
    } tmp = { .f32 = f };
    return tmp.u32;
}

static inline float bits_to_float(const uint32_t u) {
    const union {
        float f32;
        uint32_t  u32;
    } tmp = { .u32 = u };
    return tmp.f32;
}
without invoking UB in C99 and later revisions (assuming sizeof (float) == sizeof (uint32_t)).
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #80 on: December 05, 2025, 10:37:12 pm »
Type punning is undefined in most languages, and somehow it’s not a problem. Their compilers are just required to always detect it and report as an error. Whereas neither C nor C++ can do this reliably, because of a few loopholes a programmer may take to escape the type system.

memcpy does exactly what it’s supposed to do, and its behavior and elimination matches the same situations in any other language with a half-decent machine code generator. Both C and C++ do as being instructed by the programmer. It’s not compiler’s fault that a programmer invents their own interpretation of the code. I may tell to myself that memcpy makes a billion złotys appear on my desk, but I must accept the compiler will ignore such fantasy.

BTW, memmove rather than memcpy. Nowadays a reasonable implementation treats it as an alias for memmove semantics to protect programmers from hurting themselves. Thanks to this it’s a formality, but nonetheless memcpy is placing an unnecessary burden on the programmer for no benefit.

« Last Edit: December 05, 2025, 10:46:35 pm by golden_labels »
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17774
  • Country: fr
Re: C functions with "volatile" return types - what does it mean?
« Reply #81 on: December 05, 2025, 11:17:19 pm »
Few languages allow type punning (reinterpreting a type bitwise as another type) with a specific keyword. Using unions in C99+ is alright, but somehow isn't really satisfying in terms of "semantics" IMHO (YMMV).

In C++20, you have bit_cast which is supposed to do just that with no UB. (It's pretty much memcpy() under the hood, with possible optimizations when applicable). That's cool. I just don't like how much of a monster C++ has become.

In Ada, it's pretty similar to pre-C99: you basically use the 'address' property of variables. It may give weird results on some platforms.

In Modula 3 (yeah, Modula what?), there was the LOOPHOLE keyword for exactly that, with a keyword that pretty much said what it was about.
« Last Edit: December 05, 2025, 11:23:06 pm by SiliconWizard »
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #82 on: December 05, 2025, 11:36:33 pm »
I just don't like how much of a monster C++ has become.

Agreed.

Who in their right mind would want to use a language where a valid conforming program cannot be compiled!
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #83 on: December 06, 2025, 02:48:26 am »
tggzzz: did you mean: a language in which there do exist programs, syntactic validity of which can’t be determined? ;)
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #84 on: December 06, 2025, 08:57:20 am »
tggzzz: did you mean: a language in which there do exist programs, syntactic validity of which can’t be determined? ;)

Not quite. While that is surprisingly difficult for C++, it isn't the worst problem it has.

The STL is a Turing-complete language "hidden" inside C++. Some valid conforming C++ programs can never complete compilation - because they cause the compiler to emit the sequence of prime numbers during compilation! I believe most compilers give up in disgust around 1000 :)

"Hidden" is stunningly accurate! The STL language creators did not understand what hey had created and refused to believe they had created a Turing-complete language, until Erwin Unruh rubbed their noses in it[1]! If the language designers can't understand their own language, what hope do mere mortals have? Is that a sound basis for an engineering endeavour?

And then there are the reams of less esoteric problems. For a good start see the C++ FQA[sic] https://yosefk.com/c++fqa/ Based on the year-long discussions c1993 about whether it should be possible/impossible to "cast away constness", I particularly like the const correctness section.


[1] https://en.wikibooks.org/wiki/C%2B%2B_Programming/Templates/Template_Meta-Programming#History_of_TMP
« Last Edit: December 06, 2025, 09:00:27 am by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #85 on: December 06, 2025, 10:50:07 am »
Not quite. While that is surprisingly difficult for C++, it isn't the worst problem it has.

The STL is a Turing-complete language "hidden" inside C++. (…)
This is what I referenced in my comment, and what makes it impossible to determine if a C++ program is syntactically valid. Compilers do bail out, but this is a kind of resource exhaustion on a real machine. The problem itself transcends this limitation and it remains even if there was no limits.

But I also want to stress the smiley at the end. So far I didn’t hear of anybody writing such code and it’s possible it doesn’t exist among practical ones.



« Last Edit: December 06, 2025, 10:53:44 am by golden_labels »
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #86 on: December 06, 2025, 11:50:09 am »
Not quite. While that is surprisingly difficult for C++, it isn't the worst problem it has.

The STL is a Turing-complete language "hidden" inside C++. (…)
This is what I referenced in my comment, and what makes it impossible to determine if a C++ program is syntactically valid. Compilers do bail out, but this is a kind of resource exhaustion on a real machine. The problem itself transcends this limitation and it remains even if there was no limits.

But I also want to stress the smiley at the end. So far I didn’t hear of anybody writing such code and it’s possible it doesn’t exist among practical ones.

You miss the point. Syntactically valid programs cannot be compiled - which is ridiculous. (Obviously syntactically invalid programs cannot be compiled.)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #87 on: December 06, 2025, 12:14:58 pm »
You miss the point. Syntactically valid programs cannot be compiled - which is ridiculous. (Obviously syntactically invalid programs cannot be compiled.)
May I suggest reading once again what I wrote? Carefully this time.

I didn’t mention invalid programs. It’s pretty obvious invalid programs can’t be compiled, but I didn’t talk about them. Not in replies to you at least.
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4832
  • Country: us
Re: C functions with "volatile" return types - what does it mean?
« Reply #88 on: December 06, 2025, 06:38:16 pm »
You miss the point. Syntactically valid programs cannot be compiled - which is ridiculous. (Obviously syntactically invalid programs cannot be compiled.)

It's not ridiculously at all, it's of no practical importance.  It's an amusing anecdote, but it's not in the top 1000 problems with C++.

In fact while it was unintended with templates, C++ has added an entirely new class of undecidable computation deliberately.  Constexpr was specifically designed to allow you to do arbitrary computations at compile time, subject to compiler resource constraints.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #89 on: December 06, 2025, 09:10:48 pm »
You miss the point. Syntactically valid programs cannot be compiled - which is ridiculous. (Obviously syntactically invalid programs cannot be compiled.)

It's not ridiculously at all, it's of no practical importance.  It's an amusing anecdote, but it's not in the top 1000 problems with C++.

In fact while it was unintended with templates, C++ has added an entirely new class of undecidable computation deliberately.  Constexpr was specifically designed to allow you to do arbitrary computations at compile time, subject to compiler resource constraints.

The specific issue is, as you note, not particularly important. However it is one simple indication of a general problem that does affect all users: language complexity.

The committee designing C++ did not understand what they were creating, to the point that they refused to believe until their noses were forcibly and publically rubbed in the consequences. If the language is so complex that the language experts can't understand it, what chance do normal developers have? That is a real world problem for many programs.

Hence if contexpr is simple, understandable, and predictable (especially in combination with other language features), I have no problem with that.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C functions with "volatile" return types - what does it mean?
« Reply #90 on: December 06, 2025, 09:14:37 pm »
You miss the point. Syntactically valid programs cannot be compiled - which is ridiculous. (Obviously syntactically invalid programs cannot be compiled.)
May I suggest reading once again what I wrote? Carefully this time.

I didn’t mention invalid programs. It’s pretty obvious invalid programs can’t be compiled, but I didn’t talk about them. Not in replies to you at least.

Oh, I did read what you wrote in response to my post. I drew your attention to the irrelevance of deciding whether or not a program  is syntactically correct.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 190
  • Country: us
Re: C functions with "volatile" return types - what does it mean?
« Reply #91 on: December 09, 2025, 11:53:07 pm »
In C language it means absolutely nothing. In C the return value is an rvalue and C does not support cv-qualification of rvalues. Meaning that you can legally apply such qualification in the source code, but it will be ignored anyway.

While researching a different issue I came across another interesting fact about this matter.

In the original C89/90 standard as well as in C99 cv-qualifiers applied to the function return type were fully honored, i.e. even though they were "useless" they were still formally treated as part of function type. I.e. a function declared as

Code: [Select]
const int foo(const int);
would have type `const int (const int)`. It was C11 (or C17?)1 that finally updated the wording of "Function declarators (including prototypes)" section to "...then the type specified for ident is “derived-declarator-type-list function returning the unqualified version of T”". Before that the wording did not include the word "unqualified".

Type compatibility rules C (which among other things govern assignment and initializations) require exact match of function return types. For which reason before the aforementioned update the following initialization would've been considered invalid

Code: [Select]
int (*fn)(const int) = &foo;
GCC does issue a diagnostic for this initialization for all `-std=...` settings before C11. Meanwhile, Clang keeps complaining about this initialization regardless of `-std=...` setting (a bug in Clang apparently).

---
1) When I look through my collection of drafts, the first one where the word "unqualified" appears is that of C17. However, when I play aroung with GCC it is the `-std=c11` setting that triggers the change in diagnostics.
« Last Edit: December 10, 2025, 05:03:31 pm by TheCalligrapher »
 
The following users thanked this post: newbrain

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1906
  • Country: se
Re: C functions with "volatile" return types - what does it mean?
« Reply #92 on: December 10, 2025, 11:57:11 am »
It was C11 (or C17?)1)
---
1) When I look through my collection of drafts, the first one where the word "unqualified" appears is that of C17. However, when I play aroung with GCC it is the `-std=C11` setting that triggers the change in diagnostics.
Interesting stuff, thanks!

I checked the actual official standards, and, in fact, unqualified first appears in ISO/IEC 9899:2018 - matching the drafts.

I managed to trace the change from defect report DR423 to the summary DR423, and from it to the accepted resolution proposal in n1863.

So, I would say that also gcc behaviour is not consistent with C11 specification, it should also warn for -std=c11.
Admittedly, there's some ambiguity in the language, hence the DR (though the change in 6.7.6.3 is only acknowledged in the final resolution proposal).

EtA: Which settings are you using for gcc/clang? I'm not able to reproduce the behaviour: it's either there (-Wall -Wextra ) or not (no -W options), regardless of the C version selected with -std=...
« Last Edit: December 10, 2025, 12:08:56 pm by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: TheCalligrapher

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2430
  • Country: pl
Re: C functions with "volatile" return types - what does it mean?
« Reply #93 on: December 10, 2025, 12:16:29 pm »
Oh, I did read what you wrote in response to my post. I drew your attention to the irrelevance of deciding whether or not a program  is syntactically correct.
Was that needed, given not only I indicated it’s whimsical with the smiley, but I that was a reply extending your own post which already pointed to a problem of similar (ir?)relevance? The entire exchange could’ve been skipped if that was observed.
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 190
  • Country: us
Re: C functions with "volatile" return types - what does it mean?
« Reply #94 on: December 10, 2025, 05:01:25 pm »
EtA: Which settings are you using for gcc/clang? I'm not able to reproduce the behaviour: it's either there (-Wall -Wextra ) or not (no -W options), regardless of the C version selected with -std=...

I simply tried Clang on Godbolt without any extra settings. It immediately reported an "error" diagnostic for it (https://godbolt.org/z/eWYncK8qn). Historically, it appears all versions of Clang issued a diagnostic for it, with Clang 16 making it an "error", while earlier versions reported it as a "warning".

GCC 15 on Godbolt needs `-std=c99` to issue an "error" message (https://godbolt.org/z/ffY3Mnnaj), while `-std=c11` allows the code to compile silently. It GCC's timeline it was version 14 that switched from "warning" diagnostics to "error" diagnostics for many constraint violations associated with implicit pointer conversions.
 
The following users thanked this post: newbrain

Online paulca

  • Super Contributor
  • ***
  • Posts: 6361
  • Country: gb
Re: C functions with "volatile" return types - what does it mean?
« Reply #95 on: December 24, 2025, 02:17:36 pm »
How does it effect things with the RTOS is running on more than one CPU, with a shared cache and you call the getTicks function twice?

If you have zero-affinity scheduler of task, then the first call can be executed on Core 1 and the second call executed on Core 2.  Not concurrent, but interleaved across cores.

Does the keyword possibly cause the compiler to treat these return values as "cache read though"?

Otherwise, sometimes code is just there for the programmer and is meaningless to the compiler or execution environment. "Qualifiers" are a prime example.  People will still qualify imutable variables with const qualifiers even though they have no effect.  A negative aspect of this is that overuse of such qualifiers can lead to a non-matched understanding of what they do.  Eg:  Java "final" keyword being equivalent to:

int * const ptr; 

and NOT

const int* ptr;

Which is what all too many Java programmers 'think' it means.
"What could possibly go wrong?"
Current Open Projects:  68000 Self Build computer + OS.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf