Thursday, October 3, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 08:50PM +0300

On 3.10.2019 20:35, Bonita Montero wrote:
 
> The actual discussion was whether the optimization is a matter of the
> language or of the optimizer. We were not discussion definitions vs.
> declarations at this point.
 
Too bad, because those are the cause of your original problems.
 
Anyway, optimizations do not change the correctness of a program. Your
program is still invalid if you do not provide definitions for needed
entities. The fact that some compilers do not produce errors when
compiling such an invalid program is beside the point and does not make
your program correct. The compilers are not obliged to detect these
errors because the standard allows them to skip those checks (by saying
"no diagnostic required").
 
>> why do you refuse to provide a similar definition for your const
>> static class member?
 
> Because it is not necessary from what the language allows.
 
Exactly the opposite, a definition is necessary because the language,
ie. the C++ standard, requires it. Some implementations of the language
might sometimes be more lax, but one should not count on that.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 07:53PM +0200

>> language or of the optimizer. We were not discussion definitions vs.
>> declarations at this point.
 
> Too bad, because those are the cause of your original problems.
 
No, that was simply a compiler bug. The language allows read-access to
const'ed variables without definition if they're evaluatable at compile
-time.
 
> Anyway, optimizations do not change the correctness of a program.
 
AAAAAAAAAAAAH!
What the compiler is imposed to do here isn't an optimization.
 
 
> The fact that some compilers do not produce errors when
> compiling such an invalid program ...
 
My program isn't invalid. A const-variable evaluatable at compile-time
hasn't to be defined!!!
 
> Exactly the opposite, a definition is necessary because the language,
> ie. the C++ standard, requires it.
 
No.
Bo Persson <bo@bo-persson.se>: Oct 03 05:46PM +0200

On 2019-10-03 at 17:32, Bonita Montero wrote:
 
> No, the separate definition is not required if it can be evaluated to
> a compile-time constant. You can even define arrays with compile-time
> sizes on those const-members.
 
Quoting myself:
 
"However, the optimizer might often remove all references to the
constant, and then the linker will not notice that it is missing
and let you get away with it. "
 
 
In C++17 you can use constexpr instead of const, and formally get away
from the requirement for a separate definition.
 
You might want to read the last paragraph on this page:
 
https://en.cppreference.com/w/cpp/language/static
 
"If a static data member is declared constexpr, it is implicitly inline
and does not need to be redeclared at namespace scope. This
redeclaration without an initializer (formerly required as shown above)
is still permitted, but is deprecated. (since C++17)"
 
 
 
Bo Persson
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 09:11PM +0300

On 3.10.2019 20:53, Bonita Montero wrote:
 
>> Exactly the opposite, a definition is necessary because the language,
>> ie. the C++ standard, requires it.
 
> No.
 
From https://en.cppreference.com/w/cpp/language/static :
 
"If a const non-inline (since C++17) static data member or a constexpr
static data member (since C++11) is odr-used, a definition at namespace
scope is still required, but it cannot have an initializer. This
definition is deprecated for constexpr data members (since C++17)."
 
What's tricky is to see where in your program you have odr-use. For
example, passing the data member to a function via a const reference
qualifies as an odr-use. I guess that's what happened in your example.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 08:21PM +0200

> static data member (since C++11) is odr-used, a definition at namespace
> scope is still required, but it cannot have an initializer. This
> definition is deprecated for constexpr data members (since C++17)."
 
But it's not really "odr-used" because a const-variable can be compile
-time constant.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 08:24PM +0200

>> This definition is deprecated for constexpr data members (since C++17)."
 
> But it's not really "odr-used" because a const-variable can be compile
> -time constant.
 
Look at the example:
https://en.cppreference.com/w/cpp/language/definition#ODR-use
 
struct S {
static const int x = 0; // static data member
// a definition outside of class is required if it is odr-used
};
const int& f(const int& r);
 
int n = b ? (1, S::x) // S::x is not odr-used here
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !!!
: f(S::x); // S::x is odr-used here: a definition is required
Keith Thompson <kst-u@mib.org>: Oct 03 11:30AM -0700

Bonita Montero <Bonita.Montero@gmail.com> writes:
[...]
> No, that was simply a compiler bug. The language allows read-access to
> const'ed variables without definition if they're evaluatable at compile
> -time.
[...]
 
If you've encountered a compiler bug, can you provide a self-contained
test case that demonstrates it? Are you saying that the code in the
first article in this thread is such an example?
 
(I do not give permission to quote this article without a proper
attribution line.)
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 09:40PM +0300

On 3.10.2019 21:24, Bonita Montero wrote:
 
> Look at the example:
>...
> : f(S::x); // S::x is odr-used here: a definition is required
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 09:40PM +0300

On 3.10.2019 21:21, Bonita Montero wrote:
>> This definition is deprecated for constexpr data members (since C++17)."
 
> But it's not really "odr-used" because a const-variable can be compile
> -time constant.
 
Irrelevant.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 08:46PM +0200

> >...
>>            : f(S::x);  // S::x is odr-used here: a definition is required
>                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
Yes, because f is given a reference!
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 08:46PM +0200


>> But it's not really "odr-used" because a const-variable can be compile
>> -time constant.
 
> Irrelevant.
 
No, not irrelevant. A definition isn't necessary here and what you
quoted from cppreference.com exactly says that.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 08:49PM +0200

> If you've encountered a compiler bug, can you provide a self-contained
> test case that demonstrates it? Are you saying that the code in the
> first article in this thread is such an example?
 
I don't need a test. The same const-value is taken from other methods
of the class without any linker-errors when I strip the line of the
constructor. I take the value from this const-"variable" in the same
way in the constructor and the linker errors a missing definition..
 
> (I do not give permission to quote this article without a proper
> attribution line.)
 
LOL, idiot!
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 10:16PM +0300

On 3.10.2019 21:49, Bonita Montero wrote:
>> test case that demonstrates it? Are you saying that the code in the
>> first article in this thread is such an example?
 
> I don't need a test.
 
You will need to provide a self-contained test case because without that
nobody will believe you have discovered a bug in gcc. A bug in your own
code is much more likely.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 09:20PM +0200


> You will need to provide a self-contained test case because without that
> nobody will believe you have discovered a bug in gcc. A bug in your own
> code is much more likely.
 
I don't need a test because I have a workaround: when I cast
FREE_NODE to its own type, i.e. (uint32_t const), then I don't
get an error anymore. That's simply a bug.
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 10:28PM +0300

On 3.10.2019 22:20, Bonita Montero wrote:
 
> I don't need a test because I have a workaround: when I cast
> FREE_NODE to its own type, i.e. (uint32_t const), then I don't
> get an error anymore. That's simply a bug.
 
You are changing it from lvalue to rvalue, which can make a lot of
difference, for example when binding to a reference.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 09:31PM +0200

>> get an error anymore. That's simply a bug.
 
> You are changing it from lvalue to rvalue, which can make a lot of
> difference, for example when binding to a reference.
 
The value doesn't need to be defined according to what you quoted
from cppreference.com.
 
So when I write this in the constructor of my class ...
nd->pinCounter = (uint32_t const)FREE_NODE; // gcc-bug
... I get no linker-error.
 
When I write this ....
nd->pinCounter = FREE_NODE;
... I get the linker error because of a missing definition.
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 10:34PM +0300

On 3.10.2019 22:20, Bonita Montero wrote:
 
> I don't need a test because I have a workaround: when I cast
> FREE_NODE to its own type, i.e. (uint32_t const), then I don't
> get an error anymore. That's simply a bug.
 
Also, if the compiler happens to compile some version of your code
without errors, this is no proof that your code is now correct.
 
Neither is this a proof that the compiler is buggy, because
(unfortunately) C++ compilers are not obliged to catch all errors in the
program.
Paavo Helde <myfirstname@osa.pri.ee>: Oct 03 10:36PM +0300

On 3.10.2019 22:31, Bonita Montero wrote:
 
> When I write this ....
> nd->pinCounter = FREE_NODE;
> ... I get the linker error because of a missing definition.
 
And the type of nd->pinCounter is ...?
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 09:37PM +0200

>> get an error anymore. That's simply a bug.
 
> Also, if the compiler happens to compile some version of your code
> without errors, this is no proof that your code is now correct.
 
You're so learning-resistant, that's unbelievable.
So read what yo quoted from cppreference!!!
 
> Neither is this a proof that the compiler is buggy, ...
 
There is definitely a bug since in my case there hasn't to be a
definition of the static const member. Read what you quted from
cppreference.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 03 09:38PM +0200

>>      nd->pinCounter = FREE_NODE;
>> ... I get the linker error because of a missing definition.
 
> And the type of nd->pinCounter is ...?
 
The same type, but that doesn't matter.
Bo Persson <bo@bo-persson.se>: Oct 03 10:03PM +0200

On 2019-10-03 at 21:20, Bonita Montero wrote:
 
> I don't need a test because I have a workaround: when I cast
> FREE_NODE to its own type, i.e. (uint32_t const), then I don't
> get an error anymore. That's simply a bug.
 
No, that is because the cast creates a new temporary with the same value.
 
An old trick has been to use f(+FREE_NODE); when passing as a parameter.
That passes a reference to the temporary and not a reference to the
constant.
 
 
Bo Persson
Soviet_Mario <SovietMario@CCCP.MIR>: Oct 03 09:47PM +0200

On 03/10/2019 15:38, David Brown wrote:
> with a wide variety of compilers ("x86-64 gcc (trunk)" is popular, but
> not the only choice) and using whatever options you want (like "-x c
> -std=c11 -O2 -Wall -Wpedantic" as a reasonable starting point).
 
amazing ! Didn't know that
 
> ask /why/ you get particular code. It's better than asking people in
> these groups to compile code snippets for you, at least for standard
> compilers.
 
sorry but I was not aware of that site. Thanks
 
TNX also to Scott Lurndall who got me the code.
 
I'm trying to understand sth out of it but I'm very rusty
with asm
 
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Soviet_Mario <SovietMario@CCCP.MIR>: Oct 03 09:52PM +0200

On 03/10/2019 15:38, David Brown wrote:
> with a wide variety of compilers ("x86-64 gcc (trunk)" is popular, but
> not the only choice) and using whatever options you want (like "-x c
> -std=c11 -O2 -Wall -Wpedantic" as a reasonable starting point).
 
wow it does also colorize the output and flashes the areas
corresponding to the cursor ! Very invaluable feature. Molto
obbligato !
Ciao
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 03 07:00PM

On Thu, 2019-10-03, Joseph Hesse wrote:
...
> convention and not part of the language. There are library functions
> that understand this convention but the library is not part of the
> language definition.
 
Why do people keep saying that? The standard library is part of the
language.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 03 06:51PM

On Thu, 2019-10-03, David Brown wrote:
> On 03/10/2019 13:33, Jorgen Grahn wrote:
>> On Wed, 2019-10-02, Daniel wrote:
...
>> too lazy to check the source code
 
> A little look suggests that it is for parsing binary JSON formats (like
> UBJSON),
 
I can't help misreading that as "Undefined Behaviour JSON" :-)
 
Thanks. I'm not into newish file formats, and didn't know things like
this existed. (Maybe ASN.1 wasn't such a bad idea after all?)
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: