Discussion:
strong types in c - (safety samples)
(too old to reply)
Thiago Adams
2024-02-11 19:27:56 UTC
Permalink
Consider:

void f(int i);

enum E {A};

int main(){
f(A); //cake will have a warning here
}


I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are int,
but I will create a strict mode where this and other types of conversion
happens.


int main(){
f(true); //cake will have a warning here
f('A'); //not sure this one..
}

the same for enums.
Thiago Adams
2024-02-11 19:43:12 UTC
Permalink
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
    f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are int,
but I will create a strict mode where this and other types of conversion
happens.
int main(){
    f(true); //cake will have a warning here
    f('A'); //not sure this one..
}
the same for enums.
This is also part of "is C prepared to be safer language"?
This can breaks code, or it can be a diagnostic..
If it breaks code it needs to work as "warning profile" where
programmers can opt in or out.

With "warning profiles" the new semantics can be added without breaking
compatibility.
David Brown
2024-02-18 22:40:35 UTC
Permalink
[...]
In MISRA the concept is called "essential type"
a == b
The essential type of this expression is boolean.
I don't have access to the MISRA guidelines (they're not free),
but if that's what they say, it sounds like they're badly written.
They were £10, last I bought a copy, so it's not /that/ expensive. But
IMHO the "essential type" stuff is not at all good.
(It's available for £15.00 from misra.org.uk. I'm almost, but not
quite, tempted to buy a copy.)
I'll probably buy a current version, because it is somewhat relevant to
my work. (Or I could get the office to buy it.)
There's no C type called "boolean" unless you define it yourself.
The "essential type" they call "boolean" obviously isn't bool or
_Bool. It's not even a type in the C sense. And other posts here
have suggested that MISRA never actually defines what "essential
type" means.
Do the guidelines use the term "essential type" for "types" other
than "boolean"?
Oh, yes. They use it for lots of things, without good definitions,
without accurate consideration for things like integer promotion rules,
and in ways that somewhat differ from the actual C rules.
It just seems that the authors failed to think of the word
"condition", which would be a much clearer and more precise
description of what I presume they're trying to say. For example,
they could have written than any expression used as a condition
shall not be an assignment and shall not have an assignment as
any of its subexpressions, and anyone familiar with C would know
exactly what they mean. (The C standard doesn't define "condition",
but it would be easy to enumerate the contexts in which expressions
are treated as conditions, i.e., where a decision is made based on
whether the expression compares unequal to zero.)
They were trying to think of a way to say that things like the 0 or 1
int result of a comparison is not really the same thing as a normal
"int", and that the enumeration constants for an enumerated type are not
the same "essential type" as "int", and various other such things. They
are trying to invent their own type system that they think is better
than C's (and in some ways it /is/ better), and then say you should
write your C code as though it followed /their/ type system and not C's
type system.
Thiago Adams
2024-02-19 11:34:50 UTC
Permalink
[...]
In MISRA the concept is called "essential type"
a == b
The essential type of this expression is boolean.
I don't have access to the MISRA guidelines (they're not free),
but if that's what they say, it sounds like they're badly written.
Searching for MISRA "essential type" we can find something.

For instance:

https://stackoverflow.com/questions/44131637/misra-c-2012-rule-10-1-boolean-operand-to-be-used-in-case-where-expression-is-of
Chris M. Thomasson
2024-02-20 05:16:16 UTC
Permalink
Post by Thiago Adams
[...]
In MISRA the concept is called "essential type"
a == b
The essential type of this expression is boolean.
I don't have access to the MISRA guidelines (they're not free),
but if that's what they say, it sounds like they're badly written.
Searching for MISRA "essential type" we can find something.
https://stackoverflow.com/questions/44131637/misra-c-2012-rule-10-1-boolean-operand-to-be-used-in-case-where-expression-is-of
https://www.stroustrup.com/JSF-AV-rules.pdf
Keith Thompson
2024-02-20 06:23:01 UTC
Permalink
Post by Chris M. Thomasson
Post by Thiago Adams
[...]
In MISRA the concept is called "essential type"
a == b
The essential type of this expression is boolean.
I don't have access to the MISRA guidelines (they're not free),
but if that's what they say, it sounds like they're badly written.
Searching for MISRA "essential type" we can find something.
https://stackoverflow.com/questions/44131637/misra-c-2012-rule-10-1-boolean-operand-to-be-used-in-case-where-expression-is-of
https://www.stroustrup.com/JSF-AV-rules.pdf
Can you clarify the relevance? It doesn't say much about bool or
booleans and doesn't mention "essential type" at all.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */
Kaz Kylheku
2024-02-11 20:37:04 UTC
Permalink
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
Why bother with enums that are stronger than in C++.

Mainly, you don't want this:

void f(enum E);
f(42);
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Thiago Adams
2024-02-11 21:19:44 UTC
Permalink
Post by Kaz Kylheku
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
Why bother with enums that are stronger than in C++.
void f(enum E);
f(42);
In C++ this also compiles without errors.

https://godbolt.org/z/fYz4zqY3Y

(not sure if I understood you)

and

enum E {A};
void f(enum E e);

int main(){
f(1);
}

it an error in c++.
none in C

https://godbolt.org/z/7fqnv47dM
Keith Thompson
2024-02-11 22:08:53 UTC
Permalink
Post by Thiago Adams
Post by Kaz Kylheku
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
Why bother with enums that are stronger than in C++.
void f(enum E);
f(42);
In C++ this also compiles without errors.
https://godbolt.org/z/fYz4zqY3Y
(not sure if I understood you)
C++ has both C-style enums and "enum class" types, that have stricter
type checking (fewer implicit conversions).
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */
Malcolm McLean
2024-02-13 09:09:12 UTC
Permalink
Post by Kaz Kylheku
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
Why bother with enums that are stronger than in C++.
void f(enum E);
f(42);
The problem is that enums often have to go through things which are
external to the program. For example they might be stored in a database
which is read by a parser which isn't written in C. So they can't be
treated as entirely opaque and sometimes you do need to manipulate the
values.
--
Check out Basic Algorithms and my other books:
https://www.lulu.com/spotlight/bgy1mm
Ben Bacarisse
2024-02-13 14:04:50 UTC
Permalink
Post by Malcolm McLean
Post by Kaz Kylheku
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
Why bother with enums that are stronger than in C++.
void f(enum E);
f(42);
The problem is that enums often have to go through things which are
external to the program. For example they might be stored in a database
which is read by a parser which isn't written in C.
That's "a problem" (though not usually a hard one) but it's not got
anything to do with the current discussion about how C does, or should,
limit the use of implicit type conversions for enums.

Typically, "the problem" would be solved by the build system. It would
ensure that the names and values in the DB match (or correspond to)
those used in the C program, probably by generating a header file and/or
a DB table as part of the build.
Post by Malcolm McLean
So they can't be
treated as entirely opaque and sometimes you do need to manipulate the
values.
But no one is suggesting that. The discussion is about what implicit
type conversions are, or should, be allowed without any diagnostic.
--
Ben.
Tim Rentsch
2024-02-12 04:38:38 UTC
Permalink
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
int main(){
f(true); //cake will have a warning here
f('A'); //not sure this one..
}
the same for enums.
This is comp.lang.c. Please take any discussions of languages
other than C to a venue where those discussions are topical,
such as comp.lang.misc.
Thiago Adams
2024-02-12 04:48:37 UTC
Permalink
Post by Tim Rentsch
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
int main(){
f(true); //cake will have a warning here
f('A'); //not sure this one..
}
the same for enums.
This is comp.lang.c. Please take any discussions of languages
other than C to a venue where those discussions are topical,
such as comp.lang.misc.
Not sure what you mean.
This is about C and diagnostics.

For instance:

void f(int i);
int main()
{
f(true);
}

If a compiler emit a diagnostic "warning passing _Bool to integer" do
you think this is not C any more?
Tim Rentsch
2024-02-16 16:23:35 UTC
Permalink
Post by Thiago Adams
Post by Tim Rentsch
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
int main(){
f(true); //cake will have a warning here
f('A'); //not sure this one..
}
the same for enums.
This is comp.lang.c. Please take any discussions of languages
other than C to a venue where those discussions are topical,
such as comp.lang.misc.
Not sure what you mean.
This is about C and diagnostics.
void f(int i);
int main()
{
f(true);
}
If a compiler emit a diagnostic "warning passing _Bool to integer" do
you think this is not C any more?
The language you're talking about may have the same syntax
as C, but it has different semantic rules, and that is the
point of your discussion. What you're talking about is not
about C. I know you like to pretend that it's the same,
but it isn't.
Thiago Adams
2024-02-17 12:28:05 UTC
Permalink
Post by Tim Rentsch
Post by Thiago Adams
Post by Tim Rentsch
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
int main(){
f(true); //cake will have a warning here
f('A'); //not sure this one..
}
the same for enums.
This is comp.lang.c. Please take any discussions of languages
other than C to a venue where those discussions are topical,
such as comp.lang.misc.
Not sure what you mean.
This is about C and diagnostics.
void f(int i);
int main()
{
f(true);
}
If a compiler emit a diagnostic "warning passing _Bool to integer" do
you think this is not C any more?
The language you're talking about may have the same syntax
as C, but it has different semantic rules, and that is the
point of your discussion. What you're talking about is not
about C. I know you like to pretend that it's the same,
but it isn't.
Perhaps you got a bad first impression. However, Cake is indeed 100% C.
The modes I am discussing here have not been implemented yet. Even when
implemented, they are not fundamentally different from, for instance,
gcc's -werror option.

I am not pretending Cake is C. I am following the C23 standard and other
compilers like gcc, clang and msvc. Cake have some extensions, like any
other C compiler and the extensions are documented.
Blue-Maned_Hawk
2024-02-13 07:58:58 UTC
Permalink
Clang has an existing system for this with its
[[clang::enum_extensibility(open)]] and
[[clang::enum_extensibility(closed)]] attributes.
--
Blue-Maned_Hawk│shortens to
Hawk│/
blu.mɛin.dÊ°ak/
│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
Looks like it could explode at any moment!
Thiago Adams
2024-02-19 18:21:31 UTC
Permalink
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
    f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are int,
but I will create a strict mode where this and other types of conversion
happens.
It is interesting to note that treating warnings as errors is not
something new.


"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards compatibility,
GCC 13 and earlier diagnosed use of these features as warnings only.
Although these warnings have been enabled by default for many releases,
experience shows that these warnings are easily ignored, resulting in
difficult to diagnose bugs. In GCC 14, these issues are now reported as
errors, and no output file is created, providing clearer feedback to
programmers that something is wrong. "

https://gcc.gnu.org/gcc-14/porting_to.html#c
Keith Thompson
2024-02-19 18:39:51 UTC
Permalink
Post by Thiago Adams
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
    f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
It is interesting to note that treating warnings as errors is not
something new.
"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards
compatibility, GCC 13 and earlier diagnosed use of these features as
warnings only. Although these warnings have been enabled by default
for many releases, experience shows that these warnings are easily
ignored, resulting in difficult to diagnose bugs. In GCC 14, these
issues are now reported as errors, and no output file is created,
providing clearer feedback to programmers that something is wrong. "
https://gcc.gnu.org/gcc-14/porting_to.html#c
I wouldn't call that "treating warnings as errors". I'd call it "no
longer treating errors[*] as mere warnings".

[*] The C standard never requires anything other than a #error directive
as a fatal error, but it does define constraints and syntax rules,
violations of which require a diagnostic. gcc has traditionally treated
certain violations as non-fatal errors by default. With gcc 14 (not yet
released), they're apparently changing at least some of these from
warnings to fatal errors (which IMHO they should have been already).
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */
Thiago Adams
2024-02-19 19:03:14 UTC
Permalink
Post by Keith Thompson
Post by Thiago Adams
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
    f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
It is interesting to note that treating warnings as errors is not
something new.
"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards
compatibility, GCC 13 and earlier diagnosed use of these features as
warnings only. Although these warnings have been enabled by default
for many releases, experience shows that these warnings are easily
ignored, resulting in difficult to diagnose bugs. In GCC 14, these
issues are now reported as errors, and no output file is created,
providing clearer feedback to programmers that something is wrong. "
https://gcc.gnu.org/gcc-14/porting_to.html#c
I wouldn't call that "treating warnings as errors". I'd call it "no
longer treating errors[*] as mere warnings".
[*] The C standard never requires anything other than a #error directive
as a fatal error, but it does define constraints and syntax rules,
violations of which require a diagnostic. gcc has traditionally treated
certain violations as non-fatal errors by default. With gcc 14 (not yet
released), they're apparently changing at least some of these from
warnings to fatal errors (which IMHO they should have been already).
The interesting part is that it stop compilation. In this aspect the new
compiler is assuming a safer approach.

The other approach could be settings then if someone wants to update the
compiler and keeps the old code compiler it is just a matter of changing
settings. But new compiler has new defaults.
Thiago Adams
2024-02-19 19:06:24 UTC
Permalink
Post by Thiago Adams
Post by Thiago Adams
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
      f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
It is interesting to note that treating warnings as errors is not
something new.
"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards
compatibility, GCC 13 and earlier diagnosed use of these features as
warnings only. Although these warnings have been enabled by default
for many releases, experience shows that these warnings are easily
ignored, resulting in difficult to diagnose bugs. In GCC 14, these
issues are now reported as errors, and no output file is created,
providing clearer feedback to programmers that something is wrong. "
https://gcc.gnu.org/gcc-14/porting_to.html#c
I wouldn't call that "treating warnings as errors".  I'd call it "no
longer treating errors[*] as mere warnings".
[*] The C standard never requires anything other than a #error directive
as a fatal error, but it does define constraints and syntax rules,
violations of which require a diagnostic.  gcc has traditionally treated
certain violations as non-fatal errors by default.  With gcc 14 (not yet
released), they're apparently changing at least some of these from
warnings to fatal errors (which IMHO they should have been already).
The interesting part is that it stop compilation. In this aspect the new
compiler is assuming a safer approach.
The other approach could be settings then if someone wants to update the
compiler and keeps the old code compiler it is just a matter of changing
settings. But new compiler has new defaults.
Something related

https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/

"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such as
with GCC and Clang). Code that compiles with one toolchain warning-free
may not do so with another toolchain. We often see this with our
open-source projects. We primarily use Clang, and it is a common
occurrence that our CI server will report a warning when compiling our
“warning-free” code with GCC."

Safety is not portable.
Keith Thompson
2024-02-19 19:31:19 UTC
Permalink
Post by Thiago Adams
Post by Thiago Adams
Post by Thiago Adams
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
      f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
It is interesting to note that treating warnings as errors is not
something new.
"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards
compatibility, GCC 13 and earlier diagnosed use of these features as
warnings only. Although these warnings have been enabled by default
for many releases, experience shows that these warnings are easily
ignored, resulting in difficult to diagnose bugs. In GCC 14, these
issues are now reported as errors, and no output file is created,
providing clearer feedback to programmers that something is wrong. "
https://gcc.gnu.org/gcc-14/porting_to.html#c
I wouldn't call that "treating warnings as errors".  I'd call it "no
longer treating errors[*] as mere warnings".
[*] The C standard never requires anything other than a #error directive
as a fatal error, but it does define constraints and syntax rules,
violations of which require a diagnostic.  gcc has traditionally treated
certain violations as non-fatal errors by default.  With gcc 14 (not yet
released), they're apparently changing at least some of these from
warnings to fatal errors (which IMHO they should have been already).
The interesting part is that it stop compilation. In this aspect the
new compiler is assuming a safer approach.
Yes, that's pretty much what I said.
Post by Thiago Adams
Post by Thiago Adams
The other approach could be settings then if someone wants to update
the compiler and keeps the old code compiler it is just a matter of
changing settings. But new compiler has new defaults.
Something related
https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/
"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such
as with GCC and Clang). Code that compiles with one toolchain
warning-free may not do so with another toolchain. We often see this
with our open-source projects. We primarily use Clang, and it is a
common occurrence that our CI server will report a warning when
compiling our “warning-free” code with GCC."
Safety is not portable.
The problem with -Werror is that it treats *all* warnings as fatal
errors. (Which an also be an advantage if you're aware of the issues).

But that's not directly related. The changes in gcc-14 have to do with
treating some constraint violations as fatal errors rather than warnings
by default. You can use -pedantic-errors to do the same thing.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */
David Brown
2024-02-19 20:36:04 UTC
Permalink
Post by Thiago Adams
Something related
https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/
"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such as
with GCC and Clang). Code that compiles with one toolchain warning-free
may not do so with another toolchain. We often see this with our
open-source projects. We primarily use Clang, and it is a common
occurrence that our CI server will report a warning when compiling our
“warning-free” code with GCC."
Safety is not portable.
The blog's reasoning is flawed.

A project build is dependent on three main things. The source code is
one. The toolchain is another. And the build instructions - including
toolchain flags and options, linker scripts, and perhaps things like the
order of files passed to the linker. (It may also depend on things like
the time and day, if you use macros like __DATE__ and __TIME__, which is
an extraordinarily silly thing to have as a dependency.)

If you are making code that is important enough to be using CI tools,
and you have random mixtures of toolchains for different developers,
your CI server, and other parts of the system, then your development
process is badly broken. You are doing your CI and testing on a
different project from the one developers are working on, and the
projects being shipped to customers can be different again.

It can be a different matter if the deliverable for the project is just
the source code. But if it is a binary, then everything that goes into
the binary is part of the source for it, and needs to be kept under
tight control in the development process.

You might feel that it is useful to build multiple binaries using
different toolchains, perhaps to take advantage of static checks that
are available in a range of tools, or to ensure wider compatibility.
But then all those toolchains are part of the development process.

If you have not reached the stage of getting reproducible builds that
give the same binary every build for every developer, you are not ready
for tools like CI.


This is all IMHO, needless to say.
bart
2024-02-19 22:13:24 UTC
Permalink
Post by David Brown
Post by Thiago Adams
Something related
https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/
"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such
as with GCC and Clang). Code that compiles with one toolchain
warning-free may not do so with another toolchain. We often see this
with our open-source projects. We primarily use Clang, and it is a
common occurrence that our CI server will report a warning when
compiling our “warning-free” code with GCC."
Safety is not portable.
The blog's reasoning is flawed.
A project build is dependent on three main things.  The source code is
one.  The toolchain is another.  And the build instructions - including
toolchain flags and options, linker scripts, and perhaps things like the
order of files passed to the linker.  (It may also depend on things like
the time and day, if you use macros like __DATE__ and __TIME__, which is
an extraordinarily silly thing to have as a dependency.)
I often use DATE and TIME in my products to help indicate version.

It's not silly at all.

But it means the binary produced will be slightly different to one
generated 5 minutes earlier.
Thiago Adams
2024-02-20 00:59:05 UTC
Permalink
Post by bart
Post by David Brown
Post by Thiago Adams
Something related
https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/
"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such
as with GCC and Clang). Code that compiles with one toolchain
warning-free may not do so with another toolchain. We often see this
with our open-source projects. We primarily use Clang, and it is a
common occurrence that our CI server will report a warning when
compiling our “warning-free” code with GCC."
Safety is not portable.
The blog's reasoning is flawed.
A project build is dependent on three main things.  The source code is
one.  The toolchain is another.  And the build instructions -
including toolchain flags and options, linker scripts, and perhaps
things like the order of files passed to the linker.  (It may also
depend on things like the time and day, if you use macros like
__DATE__ and __TIME__, which is an extraordinarily silly thing to have
as a dependency.)
I often use DATE and TIME in my products to help indicate version.
It's not silly at all.
But it means the binary produced will be slightly different to one
generated 5 minutes earlier.
I have a better sample

Consider the literal string

u8"maçã"

if the source code is not UTF8 encoded then the result of compilation
u8"maçã" will depend where (locale) the source code is compiled because
the compiler will encode the bytes from the file according with the
locale. This happens all the time with visual studio where the default
for new files is not utft8 (fortunately the compiler have a warning now,
but not default it needs to be added)

for this reason, source code should be standardised to be UTF8. (I guess
C++ has a proposal for that)
Kaz Kylheku
2024-02-20 02:48:24 UTC
Permalink
Post by bart
I often use DATE and TIME in my products to help indicate version.
It's not silly at all.
But it means the binary produced will be slightly different to one
generated 5 minutes earlier.
The problem is that it's possible that the only difference is the
date and time. In which case it's the same program. Just the binary is
gratuitously different.

Some GNU/Linux distros nowadays are obsessed with reproducibility:
meaning that whenver the same version of the same thing is built, all
the deliverables such as executables, PDF files or whatever else is bit
for bit identical to the previous runs.

This works even if if __DATE__ and __TIME__ are used; those get frozen.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
David Brown
2024-02-20 08:43:40 UTC
Permalink
Post by bart
Post by David Brown
Post by Thiago Adams
Something related
https://embeddedartistry.com/blog/2017/05/22/werror-is-not-your-friend/
"Different vendors have different warning sets and warning detection
logic, even if they support a common array of warning settings (such
as with GCC and Clang). Code that compiles with one toolchain
warning-free may not do so with another toolchain. We often see this
with our open-source projects. We primarily use Clang, and it is a
common occurrence that our CI server will report a warning when
compiling our “warning-free” code with GCC."
Safety is not portable.
The blog's reasoning is flawed.
A project build is dependent on three main things.  The source code is
one.  The toolchain is another.  And the build instructions -
including toolchain flags and options, linker scripts, and perhaps
things like the order of files passed to the linker.  (It may also
depend on things like the time and day, if you use macros like
__DATE__ and __TIME__, which is an extraordinarily silly thing to have
as a dependency.)
I often use DATE and TIME in my products to help indicate version.
It's not silly at all.
But it means the binary produced will be slightly different to one
generated 5 minutes earlier.
It is definitely a silly thing to do if you are looking for tight
control of your builds - precisely because it means your binaries differ
on different builds. When you are running a more sophisticated
development setup - such as one where CI is appropriate - reproducible
builds are important. __DATE__ and __TIME__ guarantee that you can't do
that.

Not all development has to be with such builds, of course, and __DATE__
and __TIME__ can be helpful if you are going through a lot of changes
quickly and want to compare runs. But it means you can never go back to
your previous source and get exactly the same binary.
Thiago Adams
2024-02-22 17:39:15 UTC
Permalink
Post by Thiago Adams
Post by Thiago Adams
Post by Thiago Adams
void f(int i);
enum E {A};
int main(){
      f(A); //cake will have a warning here
}
I will create a diagnostic in cake for this and others.
Basically I will respect the standard where it says enumerators are
int, but I will create a strict mode where this and other types of
conversion happens.
It is interesting to note that treating warnings as errors is not
something new.
"The initial ISO C standard and its 1999 revision removed support for
many C language features that were widely known as sources of
application bugs due to accidental misuse. For backwards
compatibility, GCC 13 and earlier diagnosed use of these features as
warnings only. Although these warnings have been enabled by default
for many releases, experience shows that these warnings are easily
ignored, resulting in difficult to diagnose bugs. In GCC 14, these
issues are now reported as errors, and no output file is created,
providing clearer feedback to programmers that something is wrong. "
https://gcc.gnu.org/gcc-14/porting_to.html#c
I wouldn't call that "treating warnings as errors".  I'd call it "no
longer treating errors[*] as mere warnings".
[*] The C standard never requires anything other than a #error directive
as a fatal error, but it does define constraints and syntax rules,
violations of which require a diagnostic.  gcc has traditionally treated
certain violations as non-fatal errors by default.  With gcc 14 (not yet
released), they're apparently changing at least some of these from
warnings to fatal errors (which IMHO they should have been already).
The interesting part is that it stop compilation. In this aspect the new
compiler is assuming a safer approach.
The other approach could be settings then if someone wants to update the
compiler and keeps the old code compiler it is just a matter of changing
settings. But new compiler has new defaults.
I did an experiment where is possible to create "sets" of warnings.


#define SAFE_REGION \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic error \"-Wenum-compare\"")\
_Pragma("GCC diagnostic error \"-Wparentheses\"")\
_Pragma("GCC diagnostic error \"-Wuninitialized\"")

#define RESTORE \
_Pragma("GCC diagnostic pop")

enum E1 { A };
enum E2 { B };

SAFE_REGION
int main() {
int a, b;
if (a = b){}
if (A == B){}
}
RESTORE

Loading...