I think constexpr keyword is unnecessary.
Anything you do with it could/should be done with const.
Even without const , one object like (struct point){.x=1, .y=0} is a constant in my view.
So, for instance, no need for (constexpr struct point){.x=1, .y=0} here.
The VLA could have been the motivation for a new keyword, but I don’t think it matters.
On the other hand, (static struct point){.x=1, .y=0} makes sense.
If constexpr were "no-storage" I think it would make sense but it is not.
Am 11.10.2024 um 14:25 schrieb Thiago Adams:
I think constexpr keyword is unnecessary.
Anything you do with it could/should be done with const.
Even without const , one object like (struct point){.x=1, .y=0} is a
constant in my view.
So, for instance, no need for (constexpr struct point){.x=1, .y=0} here.
The VLA could have been the motivation for a new keyword, but I don’t
think it matters.
On the other hand, (static struct point){.x=1, .y=0} makes sense.
If constexpr were "no-storage" I think it would make sense but it is not.
const doesn't replace constexpr. constexpr is when you want to
assure that the variable is compile-time generated. You can't
enforse this constraint with const.
But I find all these attempts to modernize C hopeless. C wants
to remain a minimalist language and is therefore light years
behind other languages. For me, C is intended to be used when
a more advanced lanugage is not available.
constant expression make sense in C. It is not new, it is very old.
Am 11.10.2024 um 20:11 schrieb Thiago Adams:
constant expression make sense in C. It is not new, it is very old.
const has a definition and it allows non compile-time evaluated
variables.
Em 10/11/2024 4:17 PM, Bonita Montero escreveu:
Am 11.10.2024 um 20:11 schrieb Thiago Adams:
constant expression make sense in C. It is not new, it is very old.
const has a definition and it allows non compile-time evaluated
variables.
yes. but?
What I am suggesting again is remove the keyword constexpr. make const
do that.
Just to remember C++ was already like that before constexpr. In c++
const could be used as constant expressions.
What C++ could not ensure is that global variables would have a compile
time initialization.
In C all global variables are initialized in compile time.
For local variables like...
const int i = ... ;
the compiler must evaluate the initialization expression if it can be computed in compile time then i is "constexpr" does not matter if it
have or not the constexpr keyword.
Am 11.10.2024 um 21:30 schrieb Thiago Adams:
Em 10/11/2024 4:17 PM, Bonita Montero escreveu:
Am 11.10.2024 um 20:11 schrieb Thiago Adams:
constant expression make sense in C. It is not new, it is very old.
const has a definition and it allows non compile-time evaluated
variables.
yes. but?
With constexpr you could enforce that the expression you assign is compile-time evaluated. That's while constexpr would make sense.
With constexpr you could enforce that the expression you assign is
compile-time evaluated. That's while constexpr would make sense.
This is already the default in CÂ for file scope variables ...
I think constexpr keyword is unnecessary.
Anything you do with it could/should be done with const.
Even without const , one object like (struct point){.x=1, .y=0} is a constant in my view.
So, for instance, no need for (constexpr struct point){.x=1, .y=0} here.
The VLA could have been the motivation for a new keyword, but I don’t think it matters.
On the other hand, (static struct point){.x=1, .y=0} makes sense.
If constexpr were "no-storage" I think it would make sense but it is not.
Am 12.10.2024 um 15:23 schrieb Thiago Adams:
With constexpr you could enforce that the expression you assign is
compile-time evaluated. That's while constexpr would make sense.
This is already the default in CÂ for file scope variables ...
They must be optimized away by the compiler and the linker, constexpr
not. And most compile time constants that are constexpr'd in C++ are
local variables. So constexpr makes sense at least for local variables.
It depends on what constexpr means.
Em 10/12/2024 10:53 AM, Bart escreveu:
It depends on what constexpr means.
It means the initialization expression must be evaluated at compilation.
Also the declarator can be used in another expression as constant.
Sample
constexpr int a = 1;
constexpr int b = a+1;
But the expression is always something the compiler need to check if is constant or not.
So, what I suggest is if the init expression is a constant expression (something we know at compile time) then the declarator is real
constexpr (no need for a new keyword)
For instance:
const int a = 1;
const int b = a+1;
Even if not constant, the compiler can do at compile time.
for instance.
int a = 1+2;
So this has to be done anyway.
The only difference is that using 'a' cannot be used as constant in
another expression.
If you are afraid your constant is not constant expression put a static_assert. Then remove.
(C++ is a TOTAL mess. const in C++ already could be used n constant expression)
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
On 12/10/2024 22:43, Thiago Adams wrote:
Em 10/12/2024 10:53 AM, Bart escreveu:
It depends on what constexpr means.
It means the initialization expression must be evaluated at compilation.
Also the declarator can be used in another expression as constant.
Sample
constexpr int a = 1;
constexpr int b = a+1;
But the expression is always something the compiler need to check if
is constant or not.
So, what I suggest is if the init expression is a constant expression
(something we know at compile time) then the declarator is real
constexpr (no need for a new keyword)
For instance:
const int a = 1;
const int b = a+1;
Even if not constant, the compiler can do at compile time.
for instance.
int a = 1+2;
So this has to be done anyway.
The only difference is that using 'a' cannot be used as constant in
another expression.
So it looks like const/constexpr do different things, for example:
 const int a = rand();             // OK
 constexpr int b = rand();         // error
How about this:
 static int x;
 const int* p = &x;               // OK
 constexpr int* q = &x;           // ??
q's value isn't known at compile-time.
Em 10/13/2024 7:51 AM, Bonita Montero escreveu:
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
I can say the same of putting constexpr.
And it makes everything more confusing.
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
  constexpr int c = 1;
  f(c);
}
For some reason, people believe that adding constexpr will magically
improve optimization. In reality, it doesn't change anything compared to const and often reflects a misunderstanding of how the compiler works.
As a result, I end up having to explain it. In this sense, constexpr is viral and spreads confusion.
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
constexpr int c = 1;
f(c);
}
For some reason, people believe that adding constexpr will magically
improve optimization. In reality, it doesn't change anything compared
to const and often reflects a misunderstanding of how the compiler
works. As a result, I end up having to explain it. In this sense,
constexpr is viral and spreads confusion.
Am 13.10.2024 um 14:38 schrieb Thiago Adams:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
   constexpr int c = 1;
   f(c);
}
For some reason, people believe that adding constexpr will magically
improve optimization. In reality, it doesn't change anything compared
to const and often reflects a misunderstanding of how the compiler
works. As a result, I end up having to explain it. In this sense,
constexpr is viral and spreads confusion.
constexpr doesn't hurt.
On Sun, 13 Oct 2024 09:38:04 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
constexpr int c = 1;
f(c);
}
For some reason, people believe that adding constexpr will magically
improve optimization. In reality, it doesn't change anything compared
to const and often reflects a misunderstanding of how the compiler
works. As a result, I end up having to explain it. In this sense,
constexpr is viral and spreads confusion.
I see constexpr primarily as a way to enable use of functions from
math.h in static initializers.
Em 10/13/2024 9:58 AM, Bonita Montero escreveu:
Am 13.10.2024 um 14:38 schrieb Thiago Adams:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
   constexpr int c = 1;
   f(c);
}
For some reason, people believe that adding constexpr will magically
improve optimization. In reality, it doesn't change anything compared
to const and often reflects a misunderstanding of how the compiler
works. As a result, I end up having to explain it. In this sense,
constexpr is viral and spreads confusion.
constexpr doesn't hurt.
It spreads confusion, ...
... and makes code incompatible with previous versions of C "for free".
Em 10/13/2024 10:06 AM, Michael S escreveu:
On Sun, 13 Oct 2024 09:38:04 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
constexpr int c = 1;
f(c);
}
For some reason, people believe that adding constexpr will
magically improve optimization. In reality, it doesn't change
anything compared to const and often reflects a misunderstanding
of how the compiler works. As a result, I end up having to explain
it. In this sense, constexpr is viral and spreads confusion.
I see constexpr primarily as a way to enable use of functions from
math.h in static initializers.
Maybe you are thinking in C++? C does not have compile time functions.
Am 13.10.2024 um 15:09 schrieb Thiago Adams:
Em 10/13/2024 9:58 AM, Bonita Montero escreveu:
Am 13.10.2024 um 14:38 schrieb Thiago Adams:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
constexpr doesn't hurt.
It spreads confusion, ...
It can be understood in 10s.
... and makes code incompatible with previous versions of C "for free".
New improvements are always incompatible and there are mature C23
compilers.
On 13.10.2024 15:14, Bonita Montero wrote:
It can be understood in 10s.
I doubt that. - ...
What do I (in my role as a solution programmer) gain from it?
On Sun, 13 Oct 2024 10:10:19 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/13/2024 10:06 AM, Michael S escreveu:
On Sun, 13 Oct 2024 09:38:04 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/13/2024 8:49 AM, Bonita Montero escreveu:
Am 13.10.2024 um 13:37 schrieb Thiago Adams:
Yes.
constexpr is like - "require the initializer to be a constant
expression." But the compiler will have to check it anyway.
I cannot understand why you are so militantly against this
new language feature that can be understood in 10 seconds.
I have seen code like this:
void func()
{
constexpr int c = 1;
f(c);
}
For some reason, people believe that adding constexpr will
magically improve optimization. In reality, it doesn't change
anything compared to const and often reflects a misunderstanding
of how the compiler works. As a result, I end up having to explain
it. In this sense, constexpr is viral and spreads confusion.
I see constexpr primarily as a way to enable use of functions from
math.h in static initializers.
Maybe you are thinking in C++? C does not have compile time functions.
I'd expect that in the next standard a wide subset of math functions
would be allowed in constexp.
In C++ they become constexpr in C++23. If no unexpected difficulties
shows up in C++ then C would be next.
Am 13.10.2024 um 15:35 schrieb Janis Papanagnou:
On 13.10.2024 15:14, Bonita Montero wrote:
It can be understood in 10s.
I doubt that. - ...
LOL
What do I (in my role as a solution programmer) gain from it?
More expressive code.
This is not the least convincing. Since you seem to express only a language/compiler-internal theme, not any application programmers'
demand.
Am 13.10.2024 um 16:33 schrieb Janis Papanagnou:
This is not the least convincing. Since you seem to express only a
language/compiler-internal theme, not any application programmers'
demand.
I don't understand how people can argue so desperately against a
feature that is so simple and that makes the code more readable.
Am 13.10.2024 um 16:33 schrieb Janis Papanagnou:
This is not the least convincing. Since you seem to express only a
language/compiler-internal theme, not any application programmers'
demand.
I don't understand how people can argue so desperately against a
feature that is so simple and that makes the code more readable.
Em 10/13/2024 11:41 AM, Bonita Montero escreveu:
Am 13.10.2024 um 16:33 schrieb Janis Papanagnou:
This is not the least convincing. Since you seem to express only a
language/compiler-internal theme, not any application programmers'
demand.
I don't understand how people can argue so desperately against a
feature that is so simple and that makes the code more readable.
C programmers care about C simplicity.
For me, writing int i = 0; and const int i = 0; is perfectly
readable, and (unnecessarily!) adding another keyword degrades
readability.
What I am suggesting again is remove the keyword constexpr. make const
do that.
Just to remember C++ was already like that before constexpr. In c++
const could be used as constant expressions.
On 2024-10-11, Thiago Adams <thiago.adams@gmail.com> wrote:
What I am suggesting again is remove the keyword constexpr. make const
do that.
Just to remember C++ was already like that before constexpr. In c++
const could be used as constant expressions.
Really?
const int f(int x) { ... }
says that calls to f can be evaluated at compile time?
Em 10/13/2024 1:39 PM, Kaz Kylheku escreveu:
On 2024-10-11, Thiago Adams <thiago.adams@gmail.com> wrote:
What I am suggesting again is remove the keyword constexpr. make const
do that.
Just to remember C++ was already like that before constexpr. In c++
const could be used as constant expressions.
Really?
  const int f(int x) { ... }
says that calls to f can be evaluated at compile time?
I am comparing what C have so far. Only variables not functions.
Sample
const int s = 4;
int a[s];
This was always valid in C++.
Em 10/13/2024 1:39 PM, Kaz Kylheku escreveu:
On 2024-10-11, Thiago Adams <thiago.adams@gmail.com> wrote:
What I am suggesting again is remove the keyword constexpr. make const
do that.
Just to remember C++ was already like that before constexpr. In c++
const could be used as constant expressions.
Really?
const int f(int x) { ... }
says that calls to f can be evaluated at compile time?
I am comparing what C have so far. Only variables not functions.
On 2024-10-13, Thiago Adams <thiago.adams@gmail.com> wrote:
What I am suggesting again is remove the keyword constexpr. make const >>>> do that.
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
(C++ is a TOTAL mess. const in C++ already could be used n constant
expression)
C++ is five to ten times less work for the same problem.
On 10/13/2024 6:51 AM, Bonita Montero wrote:
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
(C++ is a TOTAL mess. const in C++ already could be used n constant
expression)
C++ is five to ten times less work for the same problem.
How do you measure "work'?
Am 15.10.2024 um 05:30 schrieb DFS:
On 10/13/2024 6:51 AM, Bonita Montero wrote:
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
(C++ is a TOTAL mess. const in C++ already could be used n constant
expression)
C++ is five to ten times less work for the same problem.
How do you measure "work'?
In lines of code. Imagine you would specialize a container like
unordered_map by hand in C. That would be days of work. In C++
it's one line of code and you get nearly optimal performance.
Or just think about what an emplace_back on a vector of strings
all does; if the capacity isn't sufficient a doubled vector is
allocated (libstdc++, libc++), all objects are moved there and
a new item is emplaced at the end. That's one line of code, but
in C that's a half day's work.
On 15/10/2024 12:41, Bonita Montero wrote:
Am 15.10.2024 um 05:30 schrieb DFS:
On 10/13/2024 6:51 AM, Bonita Montero wrote:
Am 12.10.2024 um 23:37 schrieb Thiago Adams:
If you are afraid your constant is not constant expression put a
static_assert. Then remove.
This is unnecessary work if you have constexpr.
(C++ is a TOTAL mess. const in C++ already could be used n constant >>>>> expression)
C++ is five to ten times less work for the same problem.
How do you measure "work'?
In lines of code. Imagine you would specialize a container like
unordered_map by hand in C. That would be days of work. In C++
it's one line of code and you get nearly optimal performance.
Or just think about what an emplace_back on a vector of strings
all does; if the capacity isn't sufficient a doubled vector is
allocated (libstdc++, libc++), all objects are moved there and
a new item is emplaced at the end. That's one line of code, but
in C that's a half day's work.
Sure, because every time you start a new C app, you're starting from zero.
There are no existing libraries to use. No online examples to use as templates. There are no examples of hashtables or growable arrays that you've implemented over decades of your own work to draw from.
There is NOTHING.
In reality it isn't like that.
Use of C++ does have the advantage when posting bits of code in on-line forums, since there are a much larger number of /standard/ libraries
that someone running your code will have access to in their
installation, if the code fragment happens to use them.
Posted C code using a non-standard library would be problematical.
That's probably why C code that use a hash-map, for example, may need to come with its implementation so it may appear to have a higher line count.
I think C could be improved a lot with something like ChatGPT to create parametrized containers.
Sure, because every time you start a new C app, you're starting from zero.
There are no existing libraries to use. No online examples to use as templates. There are no examples of hashtables or growable arrays that you've implemented over decades of your own work to draw from.
There is NOTHING.
In reality it isn't like that.
Use of C++ does have the advantage when posting bits of code in on-line forums, since there are a much larger number of /standard/ libraries
that someone running your code will have access to in their
installation, if the code fragment happens to use them.
C++ standard libraries are such shit that it's standard practice
for any organization to to have its own locally developed libraries.
On 15/10/2024 10:01, Bart wrote:
On 15/10/2024 12:41, Bonita Montero wrote:
On 10/13/2024 6:51 AM, Bonita Montero wrote:
C++ is five to ten times less work for the same problem.
In lines of code. Imagine you would specialize a container like
unordered_map by hand in C. That would be days of work. In C++
it's one line of code and you get nearly optimal performance.
Or just think about what an emplace_back on a vector of strings
all does; if the capacity isn't sufficient a doubled vector is
allocated (libstdc++, libc++), all objects are moved there and
a new item is emplaced at the end. That's one line of code, but
in C that's a half day's work.
Sure, because every time you start a new C app, you're starting from
zero.
There are no existing libraries to use. No online examples to use as
templates. There are no examples of hashtables or growable arrays that
you've implemented over decades of your own work to draw from.
[...]
Posted C code using a non-standard library would be problematical.
That's probably why C code that use a hash-map, for example, may need
to come with its implementation so it may appear to have a higher line
count.
[...]
I was planing to create something (not as advanced of course) but
something I could just write "create a vector of int" "create map of
strings to int" , "create single linked list" etc.
C++ standard libraries are such shit that it's standard practice
for any organization to to have its own locally developed libraries.
I think constexpr keyword is unnecessary.
Anything you do with it could/should be done with const.
The "const" keyword means "read-only"; ...
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr", would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be a
VLA here.
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be a
VLA here.
What practical difference would it make? Can you think of any
difference between local variables "a" and "b" defined like this?
    enum { n = 2 };
    const int c = n;
    int a[c];
    int b[n];
Can you show any situation where you could use "a" and not "b", or vice versa, or where the meaning would be different? Can you show any
compiler that treats them differently in code generation (assuming a compiler that supports enough of C99 to allow it)?
I know of no differences there. That is enough to convince me that it doesn't matter in the slightest whether it is technically a VLA or not.
On Sat, 19 Oct 2024 12:18:04 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
const int c = 2;
struct bar {
int a[c];
int b;
};
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be a
VLA here.
What practical difference would it make?
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:If not, do you have a sample where, using "const" as "constexpr",
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make? Can you think of any
difference between local variables "a" and "b" defined like this?
enum { n = 2 };
const int c = n;
int a[c];
int b[n];
Can you show any situation where you could use "a" and not "b", or
vice versa, or where the meaning would be different? Can you show any compiler that treats them differently in code generation (assuming a
compiler that supports enough of C99 to allow it)?
I know of no differences there. That is enough to convince me that it doesn't matter in the slightest whether it is technically a VLA or
not.
Em 10/19/2024 1:03 PM, David Brown escreveu:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:What practical difference would it make?
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to
be a VLA here.
I don't see any practical difference. In theory, the generated code
could be different, but I'm arguing that this doesn't really matter
and, consequently, it's not a good reason to differentiate between
const and constexpr.
Em 10/19/2024 1:53 PM, Michael S escreveu:
On Sat, 19 Oct 2024 12:18:04 -0300
Thiago Adams <thiago.adams@gmail.com> wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:const int c = 2;
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
struct bar {
int a[c];
int b;
};
Yes, but in this case, you're changing something that was previously
an error into something that now works.
David Brown <david.brown@hesbynett.no> writes:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:If not, do you have a sample where, using "const" as "constexpr",
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make? Can you think of any
difference between local variables "a" and "b" defined like this?
enum { n = 2 };
const int c = n;
int a[c];
int b[n];
Can you show any situation where you could use "a" and not "b", or
vice versa, or where the meaning would be different? Can you show any
compiler that treats them differently in code generation (assuming a
compiler that supports enough of C99 to allow it)?
I know of no differences there. That is enough to convince me that it
doesn't matter in the slightest whether it is technically a VLA or
not.
VLAs are optional in C11 and later. A conforming implementation that
doesn't support VLAs will accept `int b[n];` and reject `int a[c];`.
`sizeof a` is not a constant expression, so it can't be used in a case
label or any other context that requires a constant expression. (If
`const int c = n;` made c a constant expression, this would not apply.)
Generated code for constructs that a compiler acccepts is likely to be identical. For a VLA type with a non-constant length, the compiler must implicitly store the size somehow. For a VLA type with a length that
the compiler can evaluate at compile time, the compiler is likely to
generate code equivalent to that for a non-VLA.
Thiago Adams <thiago.adams@gmail.com> writes:
Em 10/19/2024 1:03 PM, David Brown escreveu:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:What practical difference would it make?
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to
be a VLA here.
I don't see any practical difference. In theory, the generated code
could be different, but I'm arguing that this doesn't really matter
and, consequently, it's not a good reason to differentiate between
const and constexpr.
My reasons for not wanting `const int c = 2;` to make c a constant
expression have nothing to do with any theoretical difference in
generated code.
My reason is that "const" and "constant" are two almost entirely
distinct concepts. Conflating them makes the language more confusing.
Making the name of a "const" object a constant expression adds no new capabilities beyone what we already have with "constexpr".
Though the C23 standard hasn't yet been officially released, it's too
late to make any substantive changes. C23 *will* have constexpr, and
*will not* treat const-qualified objects as constants.
If I want a name for a constant expression of type int, I can (in C23)
use "constexpr", which clearly expresses that intent. Using "const"
instead, in all versions of C up to and including C23, will result in compile-time errors.
Let's pretend that when "const" was introduced in C89, it was spelled "readonly", which more closely reflects its meaning. Would you suggest
that
readonly int n = 42;
should make n a constant expression?
What you propose would make n a constant expression if and only if its initializer is constant.
In C23, n is a constant expression if and only
if n is defined with "constexpr". If you add "constexpr" to a
declaration whose initializer is not a constant expression, it will be rejected.
Em 10/19/2024 6:48 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
Let's pretend that when "const" was introduced in C89, it was spelled "readonly", which more closely reflects its meaning. Would you suggest
that
readonly int n = 42;
should make n a constant expression?
Em 10/19/2024 6:48 PM, Keith Thompson escreveu:[...]
My reasons for not wanting `const int c = 2;` to make c a constant
expression have nothing to do with any theoretical difference in
generated code.
My reason is that "const" and "constant" are two almost entirely
distinct concepts. Conflating them makes the language more confusing.
Making the name of a "const" object a constant expression adds no new
capabilities beyone what we already have with "constexpr".
I see some differences but not enough to justify a new keyword and I
think it also generates confusion. So it is a matter of choosing what
that of confusion we want.
For instance, in file scope,
const int a = 1;
constexpr int b =1;
In both cases, because it is file scope, a and b need to be
initialized with constant expressions. I don´t see anything more
special in b compared with a to make any distinction.
On 19/10/2024 17:03, David Brown wrote:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make? Can you think of any
difference between local variables "a" and "b" defined like this?
     enum { n = 2 };
     const int c = n;
     int a[c];
     int b[n];
Can you show any situation where you could use "a" and not "b", or
vice versa, or where the meaning would be different? Can you show any
compiler that treats them differently in code generation (assuming a
compiler that supports enough of C99 to allow it)?
I know of no differences there. That is enough to convince me that it
doesn't matter in the slightest whether it is technically a VLA or not.
I can give examples where a compiler won't work, or it will generate different code, but you won't execpt it because you won't recognise the compiler, or will dismiss it, or will dismiss even gcc because
optimisations aren't used.
If it will always be gcc-O2 or higher, and it is an example just like
these (so inside a function), then probably it will generate the same code.
But that's a lot of 'if's.
Where the code is different, then gcc on Windows for example likes to generate a call to __chkstack() (to incrementally increase the stack a
page at a time in case it skips a page for a large allocation).
Em 10/19/2024 1:03 PM, David Brown escreveu:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make?
I don't see any practical difference. In theory, the generated code
could be different, but I'm arguing that this doesn't really matter and, consequently, it's not a good reason to differentiate between const and constexpr.
David Brown <david.brown@hesbynett.no> writes:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:If not, do you have a sample where, using "const" as "constexpr",
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make? Can you think of any
difference between local variables "a" and "b" defined like this?
enum { n = 2 };
const int c = n;
int a[c];
int b[n];
Can you show any situation where you could use "a" and not "b", or
vice versa, or where the meaning would be different? Can you show any
compiler that treats them differently in code generation (assuming a
compiler that supports enough of C99 to allow it)?
I know of no differences there. That is enough to convince me that it
doesn't matter in the slightest whether it is technically a VLA or
not.
VLAs are optional in C11 and later. A conforming implementation that
doesn't support VLAs will accept `int b[n];` and reject `int a[c];`.
`sizeof a` is not a constant expression, so it can't be used in a case
label or any other context that requires a constant expression. (If
`const int c = n;` made c a constant expression, this would not apply.)
Generated code for constructs that a compiler acccepts is likely to be identical. For a VLA type with a non-constant length, the compiler must implicitly store the size somehow. For a VLA type with a length that
the compiler can evaluate at compile time, the compiler is likely to
generate code equivalent to that for a non-VLA.
On 19/10/2024 21:41, Thiago Adams wrote:
Em 10/19/2024 1:03 PM, David Brown escreveu:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to be
a VLA here.
What practical difference would it make?
I don't see any practical difference. In theory, the generated code
could be different, but I'm arguing that this doesn't really matter
and, consequently, it's not a good reason to differentiate between
const and constexpr.
My point was that if there is no practical difference, then there is no reason to object to the VLA.
You can't use this as a reason for arguing that it would have been
better for "const" in C to gain the features that are now in C23 "constexpr", because this use of "const" was already allowed in C99. So the "const" vs "constexpr" discussion is an orthogonal issue - I was
asking specifically about your comment regarding your apparent dislike
of VLA's.
On 20/10/2024 11:45, David Brown wrote:
On 19/10/2024 21:41, Thiago Adams wrote:I've seen endless exampples where people inadvertently created VLAs, and where they are likely to less efficient.
Em 10/19/2024 1:03 PM, David Brown escreveu:
On 19/10/2024 17:18, Thiago Adams wrote:
Em 10/18/2024 8:54 PM, Keith Thompson escreveu:
Thiago Adams <thiago.adams@gmail.com> writes:
I think constexpr keyword is unnecessary.
Sure, most language features are strictly unnecessary.
Anything you do with it could/should be done with const.
No, absolutely not.
If not, do you have a sample where, using "const" as "constexpr",
would create problems?
The sample I know is VLA.
const int c = 2;
int a[c]; //a is VLA because c is not a constant expression.
But this is not enough to convince me because it is better not to
be a VLA here.
What practical difference would it make?
I don't see any practical difference. In theory, the generated code
could be different, but I'm arguing that this doesn't really matter
and, consequently, it's not a good reason to differentiate between
const and constexpr.
My point was that if there is no practical difference, then there is
no reason to object to the VLA.
It might start off like this:
   const int n = 10;
   int A[n];
Then they change something so that n is not evaluated until runtime
(maybe it's defined in terms of a parameter). Now the compiler will
silently generate less efficient code for a VLA, without giving the user
a chance to use an alternative.
You can't use this as a reason for arguing that it would have been
better for "const" in C to gain the features that are now in C23
"constexpr", because this use of "const" was already allowed in C99.
So the "const" vs "constexpr" discussion is an orthogonal issue - I
was asking specifically about your comment regarding your apparent
dislike of VLA's.
The advantage of constexpr AIUI is that a non-constant initialiser for n
is not allowed.
Thiago Adams <thiago.adams@gmail.com> writes:
Em 10/19/2024 6:48 PM, Keith Thompson escreveu:
For instance, in file scope,
const int a = 1;
constexpr int b =1;
In both cases, because it is file scope, a and b need to be
initialized with constant expressions. I don´t see anything more
special in b compared with a to make any distinction.
As of C23, you're right. But what if a future C standard allows
non-constant initializers for file-scope object (as C++ already does)?
Thiago Adams <thiago.adams@gmail.com> writes:
Em 10/19/2024 6:48 PM, Keith Thompson escreveu:[...]
My reasons for not wanting `const int c = 2;` to make c a constant
expression have nothing to do with any theoretical difference in
generated code.
My reason is that "const" and "constant" are two almost entirely
distinct concepts. Conflating them makes the language more confusing.
Making the name of a "const" object a constant expression adds no new
capabilities beyone what we already have with "constexpr".
I see some differences but not enough to justify a new keyword and I
think it also generates confusion. So it is a matter of choosing what
that of confusion we want.
But the new keyword already exists, and will be part of the language for years. Removing the constexpr keyword will not be possible, because
doing so would break existing code.
For instance, in file scope,
const int a = 1;
constexpr int b =1;
In both cases, because it is file scope, a and b need to be
initialized with constant expressions. I don´t see anything more
special in b compared with a to make any distinction.
As of C23, you're right. But what if a future C standard allows
non-constant initializers for file-scope object (as C++ already does)?
I used to find const confusing, as it sometimes meant 'read-only' and
other times 'immutable.'
Now, it seems less confusing to me. When const is used with variables
that can be initialized (init-declarator), it acts as 'immutable,'
meaning the storage is constant.
In other contexts, like function parameters, const means 'read-only'
because we don’t know if the storage is constant or not.
It’s also interesting to note that constexpr acts as a storage
qualifier. What the compiler needs to know when evaluating an expression
at compile time, without depending on flow analysis, is the guarantee
that the object is immutable. This makes it safe to use the value it has
at initialization when the initialization is also a compile time
expression.
const used in variables that can be initialized gives the compiler the
same guarantees.
I know there are compilers that don't support VLAs at all - that's
fair enough (and that's why I specifically mentioned it). We can
expect that compilers that can't handle VLAs at all will not support
C23 constexpr, or any suggested C++ style extensions to the semantics
of "const".
David Brown <david.brown@hesbynett.no> writes:
[...]
I know there are compilers that don't support VLAs at all - that's
fair enough (and that's why I specifically mentioned it). We can
expect that compilers that can't handle VLAs at all will not support
C23 constexpr, or any suggested C++ style extensions to the semantics
of "const".
Why would we expect that?
IIRC, Microsoft has decided not to support VLAs in its C compiler. If
they chose not to support constexpr, they could not claim C23 conformance.
David Brown <david.brown@hesbynett.no> writes:
[...]
I know there are compilers that don't support VLAs at all - that's
fair enough (and that's why I specifically mentioned it). We can
expect that compilers that can't handle VLAs at all will not support
C23 constexpr, or any suggested C++ style extensions to the semantics
of "const".
Why would we expect that?
IIRC, Microsoft has decided not to support VLAs in its C compiler. If
they chose not to support constexpr, they could not claim C23 conformance.
MS is in a somewhat different position than other C compiler
vendors. They decided - for various reasons - not to support C99 other
than parts that had direct correspondence with C++ features. Without
having followed any of the proceedings, I suspect the reason VLAs are optional in C23 is because MS wants to avoid adding more than they
have to before being able to jump to (approximate) C23 conformance. "constexpr" will be relatively easy for them, as they have it in C++
already.
David Brown <david.brown@hesbynett.no> writes:
[...]
MS is in a somewhat different position than other C compiler
vendors. They decided - for various reasons - not to support C99 other
than parts that had direct correspondence with C++ features. Without
having followed any of the proceedings, I suspect the reason VLAs are
optional in C23 is because MS wants to avoid adding more than they
have to before being able to jump to (approximate) C23 conformance.
"constexpr" will be relatively easy for them, as they have it in C++
already.
Yes, Microsoft pretty much skipped over C99, but if I recall correctly
their current C compiler has reasonably good support for C11.
[...]
On 10/21/2024 1:47 PM, Keith Thompson wrote:
David Brown <david.brown@hesbynett.no> writes:
[...]
MS is in a somewhat different position than other C compiler
vendors. They decided - for various reasons - not to support C99 other
than parts that had direct correspondence with C++ features. Without
having followed any of the proceedings, I suspect the reason VLAs are
optional in C23 is because MS wants to avoid adding more than they
have to before being able to jump to (approximate) C23 conformance.
"constexpr" will be relatively easy for them, as they have it in C++
already.
Yes, Microsoft pretty much skipped over C99, but if I recall correctly
their current C compiler has reasonably good support for C11.
Last time I checked it did not have full support for C11 threads.
//'constexpr' initializer not representable in type of object
constexpr unsigned char c= 1234;
with const it is a warning. ...
Am 20.10.2024 um 14:22 schrieb Thiago Adams:
//'constexpr' initializer not representable in type of object
constexpr unsigned char c= 1234;
with const it is a warning. ...
Good that we have constexpr now.
On 2024-10-21, Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
On 10/21/2024 1:47 PM, Keith Thompson wrote:
David Brown <david.brown@hesbynett.no> writes:
[...]
MS is in a somewhat different position than other C compiler
vendors. They decided - for various reasons - not to support C99 other >>>> than parts that had direct correspondence with C++ features. Without
having followed any of the proceedings, I suspect the reason VLAs are
optional in C23 is because MS wants to avoid adding more than they
have to before being able to jump to (approximate) C23 conformance.
"constexpr" will be relatively easy for them, as they have it in C++
already.
Yes, Microsoft pretty much skipped over C99, but if I recall correctly
their current C compiler has reasonably good support for C11.
Last time I checked it did not have full support for C11 threads.
It's a pointless wrapper for POSIX threads, which differ from Windows threads.
There is no reason to use it. Wherever POSIX threads are not found,
you can just implement *that* or find an implementation, or a
a subset that is good enough for your needs.
POSIX threads are no more or less standard than ISO C threads.
It is a gratuitous duplication.
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a special case compared to other constant expressions in C.
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a special
case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all warnings. After all, sometimes they do matter.
On 10/26/24 10:07, Vir Campestris wrote:
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a fair number of warnings that had little or no justification.
The purpose of warnings is to tell you that there might be a problem. If
the compiler is certain that there's a problem, it should generate an
error message, not a warning. Therefore, treating warnings as if they
were error messages means that you're not doing your job, as the
developer, to determine whether or not the code is actually problematic.
On 26.10.2024 17:08, James Kuyper wrote:
On 10/26/24 10:07, Vir Campestris wrote:
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn
about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a fair
number of warnings that had little or no justification.
The purpose of warnings is to tell you that there might be a problem. If
the compiler is certain that there's a problem, it should generate an
error message, not a warning. Therefore, treating warnings as if they
were error messages means that you're not doing your job, as the
developer, to determine whether or not the code is actually problematic.
We had such a null-warning policy as well (in a C++ context) and it
served us well.
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a
special case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
On 10/26/24 10:07, Vir Campestris wrote:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a
special case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to
warn about anything, even about your failure to use taboo words as identifiers. While that's a deliberately silly example, I've seen a
fair number of warnings that had little or no justification. [...]
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 26.10.2024 17:08, James Kuyper wrote:
On 10/26/24 10:07, Vir Campestris wrote:
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn >>> about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a fair >>> number of warnings that had little or no justification.
The purpose of warnings is to tell you that there might be a problem. If >>> the compiler is certain that there's a problem, it should generate an
error message, not a warning. Therefore, treating warnings as if they
were error messages means that you're not doing your job, as the
developer, to determine whether or not the code is actually problematic.
We had such a null-warning policy as well (in a C++ context) and it
served us well.
Yes, we have a similar policy. Works well. In the odd case where
one cannot eliminate the warning, a simple compiler option to not
test that particulary condition for that particular compilation unit
is a straightforward solution.
On 10/26/24 10:07, Vir Campestris wrote:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a special >>> case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a fair number of warnings that had little or no justification.
The purpose of warnings is to tell you that there might be a problem. If
the compiler is certain that there's a problem, it should generate an
error message, not a warning. Therefore, treating warnings as if they
were error messages means that you're not doing your job, as the
developer, to determine whether or not the code is actually problematic.
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
On 10/26/24 10:07, Vir Campestris wrote:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a
special case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to
warn about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a
fair number of warnings that had little or no justification. [...]
I expect that when people say "all warnings" they don't really mean
all warning conditions that compilers currently can test for, in
the sense of -Weverything in clang (and they certainly don't mean
any warning condition that is allowed to be tested, since as you
point out that is much too wide a circle to be useful). But by
saying "all warnings" the most important part of the information is concealed, because we don't know what warning conditions are meant
to be included in "all warnings." I would happily agree to fix
"all warnings" if I get to choose which set of warning conditions
is covered. Conversely, I would never agree to fix "all warnings"
if someone else is doing the choosing and doesn't define what set
of warning conditions is to be tested.
Vir Campestris <vir.campestris@invalid.invalid> writes:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a
special case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
Everyone agrees that all warnings should be fixed. Where people
differ is what set of warning conditions should be enabled.
At (or at least near) one end of the spectrum is -pedantic.
At the other end of the spectrum is -Weverything in clang. (I
confess I am sort of assuming that -Weverything includes every
warning condition known to man, which might not be the case. But
I trust people can understand what is meant by "-Weverything".)
I expect most people would advocate a point somewhere between the
two extremes. But there are different ideas about where that
point should be.
Whether warnings can or should be turned into errors is a
separate question. The first question is what set of warning
conditions should be enabled. A statement that all warnings
should be fixed is meaningless if there is no indication of
what warning conditions should be enabled.
scott@slp53.sl.home (Scott Lurndal) writes:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 26.10.2024 17:08, James Kuyper wrote:
On 10/26/24 10:07, Vir Campestris wrote:We had such a null-warning policy as well (in a C++ context) and it
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn >>>> about anything, even about your failure to use taboo words as
identifiers. While that's a deliberately silly example, I've seen a fair >>>> number of warnings that had little or no justification.
The purpose of warnings is to tell you that there might be a problem. If >>>> the compiler is certain that there's a problem, it should generate an
error message, not a warning. Therefore, treating warnings as if they >>>> were error messages means that you're not doing your job, as the
developer, to determine whether or not the code is actually problematic. >>>
served us well.
Yes, we have a similar policy. Works well. In the odd case where
one cannot eliminate the warning, a simple compiler option to not
test that particulary condition for that particular compilation unit
is a straightforward solution.
So the actual policy is to fix all warnings except in
cases where it's inconvenient to fix them?
On 10/26/24 10:07, Vir Campestris wrote:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a special >>> case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is free to warn about anything, even about your failure to use taboo words as
identifiers.
On 2024-10-26, James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
On 10/26/24 10:07, Vir Campestris wrote:
On 22/10/2024 13:48, Thiago Adams wrote:
I think a more generic feature would be to have a standard way of
promoting selected warnings to errors. This would avoid stacking
features with small differences, such as treating constexpr as a special >>>> case compared to other constant expressions in C.
I have in the past had coding standards that require you to fix all
warnings. After all, sometimes they do matter.
I believe warnings in code should be treated as alarms that require acknowledgment.
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes value from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
I would like a portable (standardized) way to achieve this.
On 2024-10-28, Thiago Adams <thiago.adams@gmail.com> wrote:
I believe warnings in code should be treated as alarms that require
acknowledgment.
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes value
from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
I would like a portable (standardized) way to achieve this.
For conversion warnings, that portable way should ideally be a cast.
Any half-decent compiler should shut up if the conversion is
explicitly requested:
const unsigned char ch = (unsigned char) 1234;
If not, complain to the compiler developer.
It works this way for conversions that are constraint violations,
like between unlike pointers. Assign a pointer to a variable of
the wrong type, and there is a required diagnostic. With a cast,
the diagnostic is not required, and it would be irksome if there
still were one.
On 29/10/2024 09:16, Thiago Adams wrote:
Edit to fix the sample
// Here we acknowledge the truncation
void f(int i) {
   ...
   const unsigned char c = i; [[!truncation]];
}
// Warning: there is no truncation to acknowledge.
void f(unsigned char i) {
   ...
   const unsigned char c = i; [[!truncation]];
}
On 29/10/2024 13:21, Thiago Adams wrote:
On 29/10/2024 09:16, Thiago Adams wrote:
Edit to fix the sample
// Here we acknowledge the truncation
void f(int i) {
    ...
    const unsigned char c = i; [[!truncation]];
}
// Warning: there is no truncation to acknowledge.
void f(unsigned char i) {
    ...
    const unsigned char c = i; [[!truncation]];
}
This should give you what you are asking for, if I have understood you correctly:
#define truncate(type, value) \
   _Generic((value), \
       type : (void) 0, \
       default : (type) value \
   )
// OK
void f1(int i) {
    const auto c = truncate(unsigned char, i);
}
// Error
void f1(unsigned char i) {
    const auto c = truncate(unsigned char, i);
}
I am not at all convinced this is a good idea. I am /certainly/ not convinced "truncate" is a good name - the general term, AFAIK, for a conversion that might try to squeeze a large value into a smaller type
is "narrowing" rather than "truncating".
You could expand the idea further and have a "truncate" macro that
checks for bounds at run time or compile time (I'd make use of the gcc extension __builtin_constant_p here, but there may be a fully standard
way to do this).
(I intend to show a general idea. There are likely better examples.)
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes value from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
On 28/10/2024 11:58, Thiago Adams wrote:
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes
value from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
If that is what you want, then why not simply say:
   const unsigned char ch = 210;
Or change it to the char to a short (or int, long, etc).
?
It's a good and helpful warning. I cannot see why you'd want to ignore it.
Do you expect to remember that 1234 really equals 210 in five years time?
On 29/10/2024 11:13, David Brown wrote:
On 29/10/2024 13:21, Thiago Adams wrote:
On 29/10/2024 09:16, Thiago Adams wrote:
Edit to fix the sample
// Here we acknowledge the truncation
void f(int i) {
    ...
    const unsigned char c = i; [[!truncation]];
}
// Warning: there is no truncation to acknowledge.
void f(unsigned char i) {
    ...
    const unsigned char c = i; [[!truncation]];
}
This should give you what you are asking for, if I have understood you
correctly:
#define truncate(type, value) \
    _Generic((value), \
        type : (void) 0, \
        default : (type) value \
    )
// OK
void f1(int i) {
     const auto c = truncate(unsigned char, i);
}
// Error
void f1(unsigned char i) {
     const auto c = truncate(unsigned char, i);
}
I am not at all convinced this is a good idea. I am /certainly/ not
convinced "truncate" is a good name - the general term, AFAIK, for a
conversion that might try to squeeze a large value into a smaller type
is "narrowing" rather than "truncating".
You could expand the idea further and have a "truncate" macro that
checks for bounds at run time or compile time (I'd make use of the gcc
extension __builtin_constant_p here, but there may be a fully standard
way to do this).
As I said,
(I intend to show a general idea. There are likely better examples.)
My objective was to show the concept of "warning acknowledge".
Name and syntax weren't important.
The solution for truncate you are proposing maybe is valid, but it is
for the specific case.
I think it is valid to think is specific cases and I can find more samples. maybe if (condition) where the condition is constant expressions.
On 29/10/2024 02:04, Kaz Kylheku wrote:
On 2024-10-28, Thiago Adams <thiago.adams@gmail.com> wrote:
I believe warnings in code should be treated as alarms that require
acknowledgment.
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes value >>> from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
I would like a portable (standardized) way to achieve this.
For conversion warnings, that portable way should ideally be a cast.
Any half-decent compiler should shut up if the conversion is
explicitly requested:
const unsigned char ch = (unsigned char) 1234;
If not, complain to the compiler developer.
It works this way for conversions that are constraint violations,
like between unlike pointers. Assign a pointer to a variable of
the wrong type, and there is a required diagnostic. With a cast,
the diagnostic is not required, and it would be irksome if there
still were one.
Yes, in this case, using a cast is the way to go with current compilers.
But, the concept of "alarm acknowledgment" removes a specific warning
that must exist. It can be a safer alternative.
(I intend to show a general idea. There are likely better examples.)
Consider this function:
void f(int i) {
...
const unsigned char c = (unsigned char)i;
}
If someone changes the type of `i` to `unsigned char`, then the cast
becomes unnecessary:
void f(unsigned char ch) {
...
const unsigned char c = (unsigned char)ch;
}
With the "alarm acknowledgment" idea (I'll just invent a syntax `[[!truncation]]`), we would get a warning if there is no actual
truncation to acknowledge. For example:
void f(unsigned char ch) {
...
const unsigned char c = (unsigned char)ch; [[!truncation]];
// Warning: there is no truncation to acknowledge.
}
[...] I am /certainly/ not
convinced "truncate" is a good name - the general term, AFAIK, for a conversion that might try to squeeze a large value into a smaller type
is "narrowing" rather than "truncating".
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 26.10.2024 17:08, James Kuyper wrote:
On 10/26/24 10:07, Vir Campestris wrote:
I have in the past had coding standards that require you to fix
all warnings. After all, sometimes they do matter.
I disapprove of that policy. A conforming implementation is
free to warn about anything, even about your failure to use
taboo words as identifiers. While that's a deliberately silly
example, I've seen a fair number of warnings that had little or
no justification. The purpose of warnings is to tell you that
there might be a problem. If the compiler is certain that
there's a problem, it should generate an error message, not a
warning. Therefore, treating warnings as if they were error
messages means that you're not doing your job, as the developer,
to determine whether or not the code is actually problematic.
We had such a null-warning policy as well (in a C++ context) and
it served us well.
Yes, we have a similar policy. Works well. In the odd case where
one cannot eliminate the warning, a simple compiler option to not
test that particulary condition for that particular compilation
unit is a straightforward solution.
So the actual policy is to fix all warnings except in
cases where it's inconvenient to fix them?
No, I never said that.
scott@slp53.sl.home (Scott Lurndal) writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Yes, we have a similar policy. Works well. In the odd case where
one cannot eliminate the warning, a simple compiler option to not
test that particulary condition for that particular compilation
unit is a straightforward solution.
So the actual policy is to fix all warnings except in
cases where it's inconvenient to fix them?
No, I never said that.
I didn't say you did. I asked a question because I didn't see
any clear statement of what the policy is that was being
followed. And I still haven't.
The question of how to shut up a warning that is truly innocuous is not
part of this policy. In my own opinion, it will often require its own
policy. That is a separate topic, because it can quite reasonably vary depending on a number of factors in the development environment, most
notably the compiler itself.
"I think truncation does not happen" is here logically equivalent to
the specific condition that ch is in the range 0 to UCHAR_MAX.
That can be asserted:
assert (0 <= ch && ch <= UCHAR_MAX);
If ch has the type unsigned char, then this condition is always
true.
We can think about a warning like that "controlling expression of
assert unconditionally true due to range of types", but it serves no
purpose. There is nothing wrong with asserting something that is
always true.
When assertions are enabled, the compiler can use their predicates
to reason about the code and not warn about conditions that are
precluded by assertions being true.
You will find that this already happens in today's compilers,
and not due to assert being treated specially. The assertion
translates into something like
if (!(0 <= ch && ch <= UCHAR_MAX)) do {
__assert_fail("0 <= ch && ch <= UCHAR_MAX", "foo.c", 42);
} while (0)
where __assert_fail is annotated a function which does not return.
On 2024-10-28, Thiago Adams <thiago.adams@gmail.com> wrote:
I believe warnings in code should be treated as alarms that require
acknowledgment.
For instance,
const unsigned char ch = 1234;
GCC:
warning: unsigned conversion from 'int' to 'unsigned char' changes value
from '1234' to '210' [-Woverflow]
The programmer might intend this behavior; in that case, the "alarm"
should be acknowledged.
I would like a portable (standardized) way to achieve this.
For conversion warnings, that portable way should ideally be a cast.
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Yes, we have a similar policy. Works well. In the odd case
where one cannot eliminate the warning, a simple compiler option
to not test that particulary condition for that particular
compilation unit is a straightforward solution.
So the actual policy is to fix all warnings except in
cases where it's inconvenient to fix them?
No, I never said that.
I didn't say you did. I asked a question because I didn't see
any clear statement of what the policy is that was being
followed. And I still haven't.
Not in so many words, no. Here is one that I have seen work well
in recent years: the code must compile without warnings. The
usefulness of this policy is strictly in making sure that any new
warnings are immediately noticed and considered, but are not an
ongoing distraction.
The question of how to shut up a warning that is truly innocuous
is not part of this policy. In my own opinion, it will often
require its own policy. That is a separate topic, because it can
quite reasonably vary depending on a number of factors in the
development environment, most notably the compiler itself.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 991 |
Nodes: | 10 (0 / 10) |
Uptime: | 119:53:41 |
Calls: | 12,958 |
Files: | 186,574 |
Messages: | 3,265,641 |