Sunday, October 31, 2021

Digest for comp.lang.c++@googlegroups.com - 1 update in 1 topic

Anand Hariharan <mailto.anand.hariharan@gmail.com>: Oct 31 09:22AM -0700

> typeid(c). typeid(a).name() should be the same as typeid(b).name(), and
> both should be different from the typeid(c).name(). Let me know what you
> find when you try that.
 
I may have missed a reply (either from someone else or even yourself) but the declaration of 'b' is a syntax error. Looks like you meant
 
int (*b)[3];
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.

Saturday, October 30, 2021

Digest for comp.lang.c++@googlegroups.com - 1 update in 1 topic

"Öö Tiib" <ootiib@hot.ee>: Oct 29 10:20PM -0700

On Friday, 29 October 2021 at 16:55:47 UTC+3, Bo Persson wrote:
 
> A problem here is that C++ introduced the const keyword first.
 
> When C got it later, the C committee decided to do it slighly differently.
 
> Now what?
 
Now we have to live with it. C+11 tried to add some clarity with constexpr
and C++17 to turn it all into mess with (sometimes also implicit) inline.
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.

Digest for comp.programming.threads@googlegroups.com - 1 update in 1 topic

Amine Moulay Ramdane <aminer68@gmail.com>: Oct 29 01:50PM -0700

Hello,
 
 
More of my philosophy about Moore's law and about Bezos' Law..
 
For RAM chips and flash memory, Moore's Law means that in eighteen months you'll pay the same price as today for twice as much storage.
But other computing components are also seeing their price versus performance curves skyrocket exponentially. Data storage doubles every twelve months.
 
More about Moore's law and about Bezos' Law..
 
"Parallel code is the recipe for unlocking Moore's Law"
 
And:
 
"BEZOS' LAW
 
The Cost of Cloud Computing will be cut in half every 18 months - Bezos' Law
 
Like Moore's law, Bezos' Law is about exponential improvement over time. If you look at AWS history, they drop prices constantly. In 2013 alone they've already had 9 price drops. The difference; however, between Bezos' and Moore's law is this: Bezos' law is the first law that isn't anchored in technical innovation. Rather, Bezos' law is anchored in confidence and market dynamics, and will only hold true so long as Amazon is not the aggregate dominant force in Cloud Computing (50%+ market share). Monopolies don't cut prices."
 
 
Thank you,
Amine Moulay Ramdane.
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.programming.threads+unsubscribe@googlegroups.com.

Friday, October 29, 2021

Digest for comp.lang.c++@googlegroups.com - 14 updates in 3 topics

Juha Nieminen <nospam@thanks.invalid>: Oct 29 04:47AM

>>And which part of "an array and a pointer are different things" do you not
>>understand?
 
> Ok, you're either just plain thick or you're trolling now.
 
I'll take that as a concession. You know you are wrong and have no response.
Juha Nieminen <nospam@thanks.invalid>: Oct 29 04:51AM

>>> int a[2][3];
 
>>Contrast that to what sizeof(a) will be here.
 
> FFS man, do you even understand whats being discussed here?
 
Yes. You claim that in func(int a[2][3]) that 'a' there is
declaring an array. According to you, it's declaring an array,
and it doesn't matter what's happening "under the hood".
 
If that were the case, if 'a' there were indeed an array, then
it would behave like an array, and be the size of an array,
just like that 'a' in the main() function.
 
Yet, it doesn't. It actually behaves exactly like a pointer,
not an array. Its size is that of a pointer, and its type is
that of a pointer, and the declaration is exactly that of a
pointer, at the language syntax level.
 
The fact that you refuse to even answer my question, ie.
what sizeof(a) is in those two cases, is telling.
Juha Nieminen <nospam@thanks.invalid>: Oct 29 05:11AM

>>And which part of "an array and a pointer are different things" do you not
>>understand?
 
> Ok, you're either just plain thick or you're trolling now.
 
Btw, I would warmly recommend that you do some self reflection.
 
Ask yourself: *Why* are you just dodging the questions presented to you,
and instead just throwing accusations and belittlement instead? If you were
right, you wouldn't have to, and instead you could present arguments to
what's actually said to you. Instead, you just dodge and throw insults.
 
I think you know that you messed up, and now just stubborningly refuse
to acknowledge it, or even to simply stop. Ask yourself why that's so,
and whether that's actually something you really want to do.
 
(Of course you will not do any of that. At least not right now. I'm
just hoping that at some point in the future you'll start doing so.)
JohnnyCameLater@whatsthetime.net: Oct 29 08:39AM

On Fri, 29 Oct 2021 04:51:57 -0000 (UTC)
 
>Yes. You claim that in func(int a[2][3]) that 'a' there is
>declaring an array. According to you, it's declaring an array,
>and it doesn't matter what's happening "under the hood".
 
Do you understand the different stages of compilation? Have you heard of
lexical analysis vs parsing vs code generation? I'm guessing not.
 
>If that were the case, if 'a' there were indeed an array, then
>it would behave like an array, and be the size of an array,
>just like that 'a' in the main() function.
 
Honestly, I just give up.
 
Its amusing how you see yourself as some kind of expert :)
 
>The fact that you refuse to even answer my question, ie.
>what sizeof(a) is in those two cases, is telling.
 
I already answered it. Yes, it'll be the size of a pointer because BY THAT
POINT it'll be treated as a pointer.
JohnnyCameLater@whatsthetime.net: Oct 29 08:40AM

On Fri, 29 Oct 2021 05:11:53 -0000 (UTC)
>>>understand?
 
>> Ok, you're either just plain thick or you're trolling now.
 
>Btw, I would warmly recommend that you do some self reflection.
 
Says Mr Depressive Aspie. Irony, much?
Tim Rentsch <tr.17687@z991.linuxsc.com>: Oct 29 06:32AM -0700


> If gcc (or whichever compiler this is) doesn't give an outright error from
> trying to assign a const pointer to a non-const one without an explicit
> cast, then it's non-standard-conforming [...]
 
I belive that statement is not correct. Can you cite a passage (or
passages) in the C++ standard that supports this assertion?
Tim Rentsch <tr.17687@z991.linuxsc.com>: Oct 29 06:34AM -0700


> There's literally zero reason not to use 'const' for pointers that
> are not intended to be used to modify the values they are pointing to.
 
There is literally zero chance that this statement is not hyperbole.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Oct 29 06:41AM -0700

> "nonportable" or "erroneous" /and/ is not covered by this
> standard's requirements>>
 
> [...]
 
Thank you for injecting a note of sanity into a discussion of
what text in the C and C++ standards means.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Oct 29 06:45AM -0700

>>> it better than others.
 
>> Says the preening fool.
 
> James is not a "preening fool". He's right.
 
To be fair, sometimes he is one, and sometimes the other.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 29 11:11AM -0700


>>> Says the preening fool.
 
>> James is not a "preening fool". He's right.
 
> To be fair, sometimes he is one, and sometimes the other.
 
To be fair, Tim, shut up.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Tim Rentsch <tr.17687@z991.linuxsc.com>: Oct 29 06:29AM -0700

> primarily meant for replacing C #define. Each C #define is TU-specific
> and gets fully preprocessed by the preprocessor, no other TU-s are
> involved.
 
It appears you have sidestepped the central question here. What a
definition like 'const int foo = 7;' (without any mention anywhere
of 'extern') does in C++ is, AFAICT, exactly the same as a similar
definition with static, namely 'static const int foo = 7;'. If
these two definitions are exactly the same (and I believe they are),
why change the meaning of the version that doesn't say 'static'?
Why introduce what appears to be a gratuitous incompatibility with C
when there was already a perfectly good construct that could be used
(and works in C++ now) for defining a local constant?
Bo Persson <bo@bo-persson.se>: Oct 29 03:55PM +0200

On 2021-10-29 at 15:29, Tim Rentsch wrote:
> Why introduce what appears to be a gratuitous incompatibility with C
> when there was already a perfectly good construct that could be used
> (and works in C++ now) for defining a local constant?
 
A problem here is that C++ introduced the const keyword first.
 
When C got it later, the C committee decided to do it slighly differently.
 
Now what?
scott@slp53.sl.home (Scott Lurndal): Oct 29 02:44PM

>definition like 'const int foo = 7;' (without any mention anywhere
>of 'extern') does in C++ is, AFAICT, exactly the same as a similar
>definition with static, namely 'static const int foo = 7;'.
 
Is that not dependent upon scope? For example:
 
class x {
static const unsigned long FRED = 0xabcdef00ul;
 
};
 
requires an additional declaration in a compilation unit, e.g.
 
const unsigned long x::FRED;
 
 
While
 
namespace y {
const unsigned long FRED = 0xabcdef00ul;
};
 
doesn't require an additional declaration.
"daniel...@gmail.com" <danielaparker@gmail.com>: Oct 28 08:29PM -0700

On Thursday, October 28, 2021 at 4:50:05 PM UTC-4, Chris M. Thomasson wrote:
 
 
> Well, what do you think?
 
> https://youtu.be/3abgNkpIY98
 
> https://www.youtube.com/watch?v=3abgNkpIY98
 
Pretty cool!
 
Daniel
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.

Thursday, October 28, 2021

Digest for comp.lang.c++@googlegroups.com - 9 updates in 3 topics

"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 28 01:49PM -0700

On 10/10/2021 10:21 PM, Branimir Maksimovic wrote:
 
>> https://www.youtube.com/watch?v=2gznap7wLeQ
> Nice work of art, show me more !
> Thanks!
 
Fwiw, Here is a new, highly experimental animation of one of my
biomorphic fractal algorithms using rings comprised of tori. Next
version will have some music! ;^)
 
Well, what do you think?
 
https://youtu.be/3abgNkpIY98
 
https://www.youtube.com/watch?v=3abgNkpIY98
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 28 11:22AM -0400

On 10/28/21 5:38 AM, Vincent Lefevre wrote:
>> perfectly clear what that description means when overflow occurs.
 
> Why "perfectly clear"??? This is even inconsistent with 7.12.1p5
> of N2596, which says:
 
7.12.1p5 describes the math library, not the handling of floating point
constants. While the C standard does recommended that "The
translation-time conversion of floating constants should match the
execution-time conversion of character strings by library functions,
such as strtod , given matching inputs suitable for both conversions,
the same result format, and default execution-time rounding."
(6.4.4.2p11), it does not actually require such a match. Therefore, if
there is any inconsistency it would not be problematic.
 
> of the mathematical result is finite but so large that the
> mathematical result cannot be represented without extraordinary
> roundoff error in an object of the specified type.
 
7.12.1p5 goes on to say that "If a floating result overflows and default
rounding is in effect, then the function returns the value of the macro
HUGE_VAL ...".
As cited above, the standard recommends, but does not require, the use
of default execution-time rounding mode for floating point constants.
HUGE_VAL is only required to be positive (7.12p6) - it could be as small
as DBL_MIN. However, on implementations that support infinities, it is
allowed to be a positive infinity (footnote 245), and when
__STDC_IEC_559__ is pre#defined by the implementation, it's required to
be positive infinity (F10p2). Even if it isn't positive infinity, it is
allowed to be DBL_MAX. DBL_MAX and positive infinity are two of the
three options allowed by 6.4.4.2p4 for constants larger than DBL_MAX, in
which case there's no conflict.
If HUGE_VAL is not one of those three values, then 6.4.4.2p4 still
applies, but 7.12.1p5 need not apply, since a match to the behavior of
strtod() is only recommended, not required..
 
> DBL_MAX and that rounds to DBL_MAX (e.g. with round-toward-zero),
> there should be an overflow, despite the fact that the FP result
> is not greater than DBL_MAX (since it is equal to DBL_MAX).
 
Agreed. As a result, the overflow exception should be signaled. However,
the C standard mandates that "Floating constants are converted to
internal format as if at translation-time. The conversion of a floating
constant shall not raise an exceptional condition or a floating-point
exception at execution time." (6.4.4.2p8). If an implementation chooses
to do the conversion at translation-time, the exception would be raised
only within the compiler, which has no obligation to do anything with
it. The implementation could generate a diagnostic, but such a constant
is not, in itself, justification for rejecting the program.
 
Therefore, if an implementation chooses to defer actual conversion until
run-time, it's required to produce the same results, which means it must
clear that overflow exception before turning control over to the user code.
 
> Moreover, with the above definition, it is DBL_NORM_MAX that is
> more likely taken into account, not DBL_MAX.
 
According to 5.2.4.2.2p19, DBL_MAX is the maximum representable finite
floating point value, while DBL_NORM_MAX is the maximum normalized
number. 6.4.4.2p4 refers only to representable values, saying nothing
about normalization. Neither 7.12.5p1 nor 7.12p6 say anything to require
that the value be normalized. Therefore, as far as I can see, DBL_MAX is
the relevant value.
 
> obtained in the FE_TONEAREST rounding mode with the IEEE 754 rules
> (where, for instance, 2*DBL_MAX rounds to +Inf, not to DBL_MAX,
> despite the fact that 2*DBL_MAX is closer to DBL_MAX than to +Inf).
 
Yes, and DBL_MAX and +Inf are two of the three values permitted by
6.4.4.2p4, so I don't see any conflict there. As far as I can see, the
value required by IEEE 754 is always one of the three values permitted
by 6.4.4.2p4, so there's never a conflict. Are you aware of any?
 
For hexadecimal floating point constants on systems with FLT_RADIX a
power of 2, 6.4.4.2p4 only allows one value - the one that is correctly
rounded - but that's precisely the same value that IEEE 754 requires.
Juha Nieminen <nospam@thanks.invalid>: Oct 28 05:17AM


>>No, it doesn't. It declares a pointer. What do you think this will print?
 
> Which parts of "syntax" and "under the hood" is confusing you. Perhaps in your
> own language?
 
And which part of "an array and a pointer are different things" do you not
understand?
 
The function is *not* taking an array. It's taking a pointer. This is not just
"it's taking a pointer under the hood". It's taking a pointer with respect to
C syntax. Just because there are several alternative syntaxes to specify the
type of pointer doesn't matter. It's still a pointer. Not just in its
underlying representation, but at the language syntax level. These three
declarations are identical and mean the same thing, they are merely using
alternative syntaxes to express the same thing:
 
void foo(int *ptr) {}
void foo(int ptr[]) {}
void foo(int ptr[10]) {}
 
C++ supports function overloading. However, if you try to do the above in C++
you'll get redefinition errors, because all three are identical.
 
Contrast that with, for example:
 
void foo(int *ptr) {}
void foo(int &ptr) {}
 
Those two might result in identical binaries under the hood, but they are
syntactically different, and will not cause a redefinition error.
Juha Nieminen <nospam@thanks.invalid>: Oct 28 05:20AM

> {
> a[10][50] = 123;
> }
 
If 'a' there is an array, what will sizeof(a) be?
 
> int main()
> {
> int a[2][3];
 
Contrast that to what sizeof(a) will be here.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 27 11:10PM -0700

On 10/27/2021 10:20 PM, Juha Nieminen wrote:
>> a[10][50] = 123;
>> }
 
> If 'a' there is an array, what will sizeof(a) be?
 
It can be equal to sizeof(void*)...
 
 
JohnnyCameLater@whatsthetime.net: Oct 28 09:29AM

On Wed, 27 Oct 2021 17:21:34 +0100
>>>in this context, what [] means is pointer semantics.
 
>> Oh really?
 
>Yes.
 
No.
 
>> 1 warning generated.
 
>> Nuff said.
 
>Not really. Note that the compiler does not complain about the first
 
Yes really. The parser is treating it as an array and doing bounds checking.
The fact it gets implicitely converted into a pointer later is irrelevant.
 
>index (10) being out of bounds. That's because (despite the badly
 
So what? Clang compilation generally stops at the first error it finds.
 
>x.c:6:18: note: while referencing 'a'
> 6 | void func2(int (*a)[3])
> | ~~~~~~^~~~~
 
Thank you for proving my point that the gcc parser also treats it as an array.
JohnnyCameLater@whatsthetime.net: Oct 28 09:30AM

On Thu, 28 Oct 2021 05:17:54 -0000 (UTC)
>> own language?
 
>And which part of "an array and a pointer are different things" do you not
>understand?
 
Ok, you're either just plain thick or you're trolling now.
JohnnyCameLater@whatsthetime.net: Oct 28 09:30AM

On Thu, 28 Oct 2021 05:20:52 -0000 (UTC)
>> {
>> int a[2][3];
 
>Contrast that to what sizeof(a) will be here.
 
FFS man, do you even understand whats being discussed here?
Bart <bc@freeuk.com>: Oct 28 11:20AM +0100

> The fact it gets implicitely converted into a pointer later is irrelevant.
 
>> index (10) being out of bounds. That's because (despite the badly
 
> So what? Clang compilation generally stops at the first error it finds.
 
(Does it?)
 
>> 6 | void func2(int (*a)[3])
>> | ~~~~~~^~~~~
 
> Thank you for proving my point that the gcc parser also treats it as an array.
 
In:
 
void func(int a[2][3]) ...
 
the type of 'a' is:
 
'pointer to array 3 of int'.
 
For parameters, the first level of a type starting T[] is reduced to T*,
a pointer: T[][] becomes T(*)[].
 
So arrays exist in the lower dimensions, but never in the primary one,
which is where it would be necessary for arrays to be passed by value.
 
But apart from that quibble, you're spot on. I can see now that you were
pretty much right about everything, and all the long-standing experts
here have no idea what they're talking about.
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.

Wednesday, October 27, 2021

Digest for comp.lang.c++@googlegroups.com - 1 update in 1 topic

Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Oct 27 06:21PM +0100

On Wed, 27 Oct 2021 19:02:46 +0200
> On 27/10/2021 18:41, Chris Vine wrote:
> > On Wed, 27 Oct 2021 11:07:03 +0200
> > David Brown <david.brown@hesbynett.no> wrote:
[snip]
> > }
 
> Yes, that is much the same as a reference in C++ (though you'd be
> slightly closer with "char (*arr)[10]" ).
 
You are agreeing with me: I think you understand that although I am not
entirely sure.
 
The overarching point is that in the signature:
 
void func (char arr[10])
 
'arr' is not the name of an array at all but is the name of a pointer to
char. You can pass func the address of any char object, whether or not
a member of an array. This is the fundamental misunderstanding by the
person in question.
 
With:
 
void func (char (&arr)[10])
 
'arr' is a reference to an char array of size 10 and only that.
 
With:
 
void func (char (*arr)[10])
 
'arr' is a pointer to an char array of size 10 and only that.
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.

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

Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:43AM


> And you didn't bother to mention the diagnostic? I get
> warning: ISO C++ forbids converting a string constant to ???char*??? [-Wwrite-strings]
> And of course with "-pedantic-errors" it becomes a fatal error.
 
If gcc (or whichever compiler this is) doesn't give an outright error from
trying to assign a const pointer to a non-const one without an explicit
cast, then it's non-standard-conforming and I would classify it as a
defect in the compiler.
 
I think that the compiler should be fully standard-conforming by default,
and be more permissive and have non-standard extensions and behavior only
when explicitly specified using command-line parameters. Not the other
way around.
Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:44AM

> Sorry, I have limited tolerance for smart asses so yes, I stopped reading.
 
Then why are you responding?
Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:57AM


> [hopeless effort at self justification]
 
> You said arrays couldn't be declared as parameters. I showed you they could,
> end of. What the compiler does with it under the hood is irrelevant.
 
You seem to be confusing pointers with arrays. Which is not completely
unexpected given that this confusing is very common among less
experienced C (and C++) programmers, as the language makes that
distinction oftentimes hard to discern.
 
(I know that you will not read past this, but I'm going to try to
explain it anyway.)
 
An array and a pointer are not the same thing, not even in C. While an
array can often be confused with a pointer, because an array almost always
implicitly converts to a pointer-to-its-fist-element implicitly whenever
one is needed, they are not the same thing. The most prominent situation
where this distinction is made is when using the sizeof operator.
The sizeof of a pointer will be just the size of the pointer itself
(typically 4 or 8). The sizeof of an array will be the entire amount
of bytes that the array takes.
 
uint32_t values[10];
uint32_t *ptr = values;
 
sizeof(values); // will be 40.
sizeof(ptr); // will typically be 4 or 8.
 
In C, and C++, you cannot pass arrays by value to a function as-is.
You can only pass a pointer to an array. (This pointer will carry
no information about the number of elements in the array, even if
you use the confusing syntax where it looks like it does.)
 
The only way you can pass an array to a function by value (both
in C and C++) is by enclosing it inside a struct (or class) and
passing an object of that type by value:
 
struct MyArray
{
int values[10];
};
 
// Genuinely gets the entire array by value, not just a pointer:
void foo(struct MyArray theArray);
 
You can use the array syntax in a function parameter declaration, but
that's just confusing syntax sugar:
 
// It does not get an array of 10 elements by value, it's just
// getting a pointer. The "10" in the declaration is meaningless:
void foo(int values[10])
{
printf("%u\n", sizeof(values)); // will print 4 or 8, not 40
}
 
Honestly, I think it was a bad idea to add that syntactic sugar to C.
It only causes confusion for no benefit.
Juha Nieminen <nospam@thanks.invalid>: Oct 27 05:01AM

>>> Bus error: 10
 
>>For starters, that's in no way guaranteed to happen. Learn standard C.
 
> It is on *nix and thats good enough for me.
 
I would like a citation to the Single Unix Specification, or to POSIX,
that states so.
 
(I'm not saying it's not there. I just find it doubtful because not all
CPU architectures have support for that.)
 
>>Secondly, if you think that a runtime diagnostic is as good as a compile-time
>>diagnostic, then you have still a LOT to learn about software development.
 
> All I'm saying is the bug would exhibit itself pretty quickly.
 
Then you are very inexperienced in software development.
Juha Nieminen <nospam@thanks.invalid>: Oct 27 05:04AM


> Noooo! Really??
 
> Have you actually read anything I wrote or are you just jumping on the
> bandwagon of what others have said in order to try and sound clever?
 
Actually he has. He read your assertion that "[] means modifiable
and * means non-modifiable", and is proving you wrong: * can be
perfectly well modifiable.
 
Of course you will never acknowledge this. Instead you'll just start
dodging with insults.
David Brown <david.brown@hesbynett.no>: Oct 27 08:29AM +0200

On 27/10/2021 06:43, Juha Nieminen wrote:
> trying to assign a const pointer to a non-const one without an explicit
> cast, then it's non-standard-conforming and I would classify it as a
> defect in the compiler.
 
You may /prefer/ an error (stopping compilation) rather than a warning,
but the standard does not require it. A diagnostic message is all that
is needed on constraint errors.
 
I guess someone decided that a warning (always enabled, without
requiring any flags) is a good compromise for the convenience of people
converting old C code to C++.
 
(I personally would prefer a hard error on this and many other faults in
code, requiring particular options to allow people to compile
questionable code. But backwards compatibility applies to build systems
as well - there is a strong feeling that where possible, code that could
be compiled with particular flags before should continue to be compilable.)
 
It's the website rextester.com that is at fault in hiding warnings by
default. That is idiotic, IMHO.
 
> and be more permissive and have non-standard extensions and behavior only
> when explicitly specified using command-line parameters. Not the other
> way around.
 
In this respect, gcc /is/ fully conforming.
 
From C++14, 1.4p2 "Implementation compliance"
 
"""
If a program contains a violation of any diagnosable rule or an
occurrence of a construct described in this Standard as
"conditionally-supported" when the implementation does not support that
construct, a conforming implementation shall issue at least one
diagnostic message.
"""
RacingRabbit@watershipdown.co.uk: Oct 27 07:57AM

On Tue, 26 Oct 2021 12:23:37 -0400
 
>No, I said "it's not permitted to declare functions that take arrays as
>arguments, but it is permitted to declare a function parameter as if it
>were an array."
 
There is no difference. As I said, what the compiler does with it under the
hood is not the point. The syntax declares an array.
 
>When I run that program, it says "pointer". What do you get when you run it?
 
Same. Not the point, its declared as an array.
Juha Nieminen <nospam@thanks.invalid>: Oct 27 08:47AM

>>were an array."
 
> There is no difference. As I said, what the compiler does with it under the
> hood is not the point. The syntax declares an array.
 
No, it doesn't. It declares a pointer. What do you think this will print?
 
#include <stdio.h>
 
void foo(int array[10])
{
printf("foo: sizeof(array) = %lu\n", sizeof(array));
}
 
int main()
{
int array[10];
int *ptr = array;
printf("main: sizeof(array) = %lu\n", sizeof(array));
printf("main: sizeof(ptr) = %lu\n", sizeof(ptr));
foo(array);
}
David Brown <david.brown@hesbynett.no>: Oct 27 11:07AM +0200

> hood is not the point. The syntax declares an array.
 
>> When I run that program, it says "pointer". What do you get when you run it?
 
> Same. Not the point, its declared as an array.
 
Do you have trouble understanding the difference between an array, and a
pointer to the first element of the array?
 
C arrays are /never/ passed to functions as parameters, nor are they
used directly in most expressions. (You can pass a struct that contains
an array as a field, but that's a struct, not an array.) It is a major
inconsistency in the type system of C, but one that works well in practice.
 
Do you know the difference between :
 
int ar1[10];
 
and
 
std::array<int, 10> ar2;
 
and how these may be passed to functions?
JohnnyCameLater@whatsthetime.net: Oct 27 02:29PM

On Wed, 27 Oct 2021 08:47:42 -0000 (UTC)
 
>> There is no difference. As I said, what the compiler does with it under the
>> hood is not the point. The syntax declares an array.
 
>No, it doesn't. It declares a pointer. What do you think this will print?
 
Which parts of "syntax" and "under the hood" is confusing you. Perhaps in your
own language?
 
"syntaksi"
"konepellin alla"
 
Any clearer?
JohnnyCameLater@whatsthetime.net: Oct 27 02:30PM

On Wed, 27 Oct 2021 11:07:03 +0200
 
>> Same. Not the point, its declared as an array.
 
>Do you have trouble understanding the difference between an array, and a
>pointer to the first element of the array?
 
Do you have trouble understanding plain English? The syntax declares an array,
the fact the compiler converts that into a pointer isn't the point. Pun
intended.
David Brown <david.brown@hesbynett.no>: Oct 27 05:30PM +0200


> Do you have trouble understanding plain English? The syntax declares an array,
> the fact the compiler converts that into a pointer isn't the point. Pun
> intended.
 
I don't know whether you are trolling, or if you are simply so arrogant
that you would rather stay ignorant and insult people than admit to
making a mistake and appreciate the help and advice you are given.
Either way, feel free to come back with questions once you have grown up
a little, and feel free to stay away until that day.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 11:38AM -0400

>> were an array."
 
> There is no difference. As I said, what the compiler does with it under the
> hood is not the point. The syntax declares an array.
 
The syntax uses [] rather than *. The semantics are those of a pointer,
not an array.
 
The semantics are NOT "under the hood" - they restrict what you can do
with the function without violating a constraint. They determine what
result you get when you apply the sizeof() or unary & operators to the
parameter. Most importantly, they determine what happens if you write
expressions such as "parameter[1] = 5".
 
Getting back to my original statement, declaring a parameter with
pointer semantics using the [] syntax does not allow you to pass an
array as the corresponding argument in the function call. All you can
pass is a pointer to the first element of the array - which is what any
lvalue of array type will be converted into if passed as an argument to
such a function.
 
Since C uses "pass by value" exclusively, if you were able to pass an
array as an argument, then the corresponding parameter would be a
separate array object with a different address, initialized by copying
from the array argument. Evaluation the expression "parameter[1] = 5"
would only affect the parameter, it would have no effect on the array
argument.
You can get some idea of how C would behave if such declarations were
possible, by declaring a struct type containing an array. Such a struct
could be passed into or returned by a function by value. It's
syntactically different from, but semantically equivalent to, passing
around the array itself by value.
 
The actual C semantics of such a function call are that the
corresponding parameter is a separate pointer object filled in by
copying the value of the pointer that the lvalue was converted to.
Evaluating the expression "parameter[1] = 5" would set the second
element of the array to 5.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 11:39AM -0400

> On Wed, 27 Oct 2021 11:07:03 +0200
> David Brown <david.brown@hesbynett.no> wrote:
...
 
> Do you have trouble understanding plain English? The syntax declares an array,
> the fact the compiler converts that into a pointer isn't the point. Pun
> intended.
 
"array" vs. "pointer is a matter of semantics. [] vs * is a matter of
syntax. All you can say about the syntax is that it contains []. In most
contexts, [] in the syntax of a declaration corresponds to array
semantics. However, the standard is quite explicit about the fact that,
in this context, what [] means is pointer semantics.
 
This is not just quibbling. It determine which arguments can be passed
to the function without violating a constraint. Two function prototypes
are compatible only if the type that one of them declares for a given
parameter is compatible with the type declared by the other for that
same parameter. If one function prototype uses "int array[]" for one
parameter, and the other uses "* int pointer" for the same parameter,
those two prototypes are compatible.
JohnnyCameLater@whatsthetime.net: Oct 27 03:46PM

On Wed, 27 Oct 2021 17:30:43 +0200
>> the fact the compiler converts that into a pointer isn't the point. Pun
>> intended.
 
>I don't know whether you are trolling, or if you are simply so arrogant
 
Pot -> kettle.
 
>making a mistake and appreciate the help and advice you are given.
>Either way, feel free to come back with questions once you have grown up
>a little, and feel free to stay away until that day.
 
Go fuck yourself you patronising jerk.
JohnnyCameLater@whatsthetime.net: Oct 27 03:49PM

On Wed, 27 Oct 2021 11:38:54 -0400
>> hood is not the point. The syntax declares an array.
 
>The syntax uses [] rather than *. The semantics are those of a pointer,
>not an array.
 
The syntax defines an array. Why do you think you get compiler warnings if
you go OOB with an index value? Try it.
 
>The semantics are NOT "under the hood" - they restrict what you can do
 
Yes, they are.
 
tl;dr
JohnnyCameLater@whatsthetime.net: Oct 27 03:51PM

On Wed, 27 Oct 2021 11:39:16 -0400
>contexts, [] in the syntax of a declaration corresponds to array
>semantics. However, the standard is quite explicit about the fact that,
>in this context, what [] means is pointer semantics.
 
Oh really?
 
fenris$ cat t.c
#include <stdio.h>
 
void func(int a[2][3])
{
a[10][50] = 123;
}
 
 
int main()
{
int a[2][3];
func(a);
return 0;
}
fenris$ cc t.c
t.c:5:2: warning: array index 50 is past the end of the array (which contains 3
elements) [-Warray-bounds]
a[10][50] = 123;
^ ~~
t.c:3:11: note: array 'a' declared here
void func(int a[2][3])
^
1 warning generated.
 
Nuff said.
scott@slp53.sl.home (Scott Lurndal): Oct 27 04:13PM

>On 27/10/2021 16:30, JohnnyCameLater@whatsthetime.net wrote:
 
>>> On 27/10/2021 09:57, RacingRabbit@watershipdown.co.uk wrote:
 
>I don't know whether you are trolling,
 
Given the choice of nyms,and the name changes, my assumption has
been trolling. Best to simply ignore such posts.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Oct 27 05:21PM +0100

>>semantics. However, the standard is quite explicit about the fact that,
>>in this context, what [] means is pointer semantics.
 
> Oh really?
 
Yes.
 
> ^
> 1 warning generated.
 
> Nuff said.
 
Not really. Note that the compiler does not complain about the first
index (10) being out of bounds. That's because (despite the badly
worded note) it's only the three-element objects pointed to by 'a' that
are in fact arrays with a known bound. Some compilers explain the issue
more clearly.
 
Here's gcc 11.2 giving much better, but identical, notes about these two
functions:
 
void func(int a[2][3])
{
a[10][50] = 123;
}
 
void func2(int (*a)[3])
{
a[10][50] = 123;
}
 
x.c: In function 'func':
x.c:3:11: warning: array subscript 50 is above array bounds of 'int[3]' [-Warray-bounds]
3 | a[10][50] = 123;
| ~~~~~^~~~
x.c:1:15: note: while referencing 'a'
1 | void func(int a[2][3])
| ~~~~^~~~~~~
x.c: In function 'func2':
x.c:3:11: warning: array subscript 50 is above array bounds of 'int[3]' [-Warray-bounds]
3 | a[10][50] = 123;
| ~~~~~^~~~
x.c:6:18: note: while referencing 'a'
6 | void func2(int (*a)[3])
| ~~~~~~^~~~~
 
--
Ben.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 12:26PM -0400

> On Wed, 27 Oct 2021 11:39:16 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
...
>> semantics. However, the standard is quite explicit about the fact that,
>> in this context, what [] means is pointer semantics.
 
> Oh really?
 
Yes, really.
 
> void func(int a[2][3])
> ^
> 1 warning generated.
 
The standard imposes no requirements on diagnostics - in particular, it
does not require them to correctly describe the problem - many
implementations occasionally generate incorrectly worded diagnostics,
even when describing legitimate errors, and this warning is one example.
The actual type of a is int(*)[3], not int[2][3], a fact that you can
confirm using sizeof(a) or &a (the difference between those types
disappears in all other contexts, due to the implicit array=>pointer
conversion).
 
This message is posted to C++. While C++ has many differences from C,
this isn't one of them, and in C++ a more convenient way to check the
type of a is to use typeid(a).name(). Unfortunately, the resulting
string is implementation-defined - on my machine it is a coded version
of the type, rather than a proper C++ type specification. However, if
you declare
 
int b(*)[3];
int c[2][3];
 
then you should find that typeid(a)==typeid(b), and typeid(a) !=
typeid(c). typeid(a).name() should be the same as typeid(b).name(), and
both should be different from the typeid(c).name(). Let me know what you
find when you try that.
 
There is an array bounds violation in your code, but it's not in a
itself, which is not an array. a is a pointer that can be used to point
at any unqualified array with an element type of int[3], regardless of
how large. However, whatever array you point a at, if a[10] refers to an
actual element of that array, then a[10][50] violates the bounds of the
3-element array that a[10] points at, not the bounds of a itself, which
has none.
 
You'll get the same error if you change a[10][50] to a[1][50], and there
wouldn't be any problem in func() itself if you changed it to a[10][2].
 
If you pass a pointer to func() which will still point at a different
element of the same array after 10 is added to it, then a[10][2] inside
of func() would also have defined behavior - which would be to change
the corresponding element of the pointed-at array, rather than the
corresponding element of a, which has none.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 12:36PM -0400

> On Wed, 27 Oct 2021 11:38:54 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
>> On 10/27/21 3:57 AM, RacingRabbit@watershipdown.co.uk wrote:
...
>> not an array.
 
> The syntax defines an array. Why do you think you get compiler warnings if
> you go OOB with an index value? Try it.
 
I did try it, and I don't get a compiler warning if I violate the
supposed leading dimension of that array, which is the dimension that
gets "adjusted" into a pointer:
 
 
static void func (int a[2][3])
{
a[4][2] = 123;
}
 
int main(void)
{
int b[8][3] = 0;
func(b);
return b[4][2];
}
 
Subscripting with a[i][j] with j>2 would be just as much of an array
violation if the type of a is int(*)[3] as it would be if the type of a
were int[2][3].
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Oct 27 05:41PM +0100

On Wed, 27 Oct 2021 11:07:03 +0200
> used directly in most expressions. (You can pass a struct that contains
> an array as a field, but that's a struct, not an array.) It is a major
> inconsistency in the type system of C, but one that works well in practice.
 
I know what you mean - they are never passed by value as parameters -
but they can be passed by reference as an array rather than as a pointer
to their first element. In C++ you have this available: there is no
pointer decay and it will print 10:
 
void func (char (&arr)[10]) {
std::cout << sizeof(arr) << std::endl;
}
 
int main() {
char arr9[9];
char arr10[10];
// func(arr9); // won't compile
func(arr10); // OK
}
 
In C and C++ you have this, which will also print 10:
 
void func (char (*arr)[10]) {
std::cout << sizeof(*arr) << std::endl;
}
 
int main() {
char arr9[9];
char arr10[10];
// func(&arr9); // won't compile
func(&arr10); // OK
}
 
None of this detracts from the fact that your nym-shifting correspondent
is not only clueless but also unable to learn.
 
David Brown <david.brown@hesbynett.no>: Oct 27 07:02PM +0200

On 27/10/2021 18:41, Chris Vine wrote:
> but they can be passed by reference as an array rather than as a pointer
> to their first element. In C++ you have this available: there is no
> pointer decay and it will print 10:
 
You can do that in C++, not in C. References in C++ are basically the
same concept as const pointers (as distinct from pointers to const),
just with a slightly different syntax. Your "func" here is not taking
an array as a value parameter (like C, you can't do that in C++ with
plain arrays), nor is it using array syntax as a means of specifying a
pointer to the first element. It is a pointer to an /array/.
 
 
> void func (char (*arr)[10]) {
> std::cout << sizeof(*arr) << std::endl;
> }
 
Yes, that is much the same as a reference in C++ (though you'd be
slightly closer with "char (*arr)[10]" ).
 
 
(I think that references are often better than pointers - they can be
safer and clearer. But they are not fundamentally different, as can be
seen by looking at implementations - they are convenient syntactic sugar.)
 
 
> None of this detracts from the fact that your nym-shifting correspondent
> is not only clueless but also unable to learn.
 
Indeed.
"Heitber Andrés Montilla Ramirez" <montillaramirezh@gmail.com>: Oct 26 06:24PM -0700

Hi everyone I want to know why this error apperars to my code, I'm trying to do an OpenGL App Using codeblocks, I re-checked the code twice with the original tutorial and everything is ok.
now the compiler throws the following error:
 
|error: invalid conversion from 'const void*' to 'HANDLE {aka void*}' [-fpermissive]|
 
I want your help to solve this issue.
 
 
 
#define GLUT_DISABLE_ATEXIT_HACK
#define GLEW_STATIC
 
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>

Tuesday, October 26, 2021

Digest for comp.lang.c++@googlegroups.com - 24 updates in 2 topics

Manfred <noname@add.invalid>: Oct 26 05:15PM +0200

On 10/25/2021 8:11 PM, Keith Thompson wrote:
 
> I don't see how the omission of "upon use of a nonportable or erroneous
> program construct or of erroneous data" in the C++ standard makes any
> real difference.
 
It depends on the reader: whether it is some sort of text processing
machine, a language lawyer or a human being.
 
 
> In all cases, "undefined behavior" is determined either by an explicit
> statement or by the omission of any definition of the behavior (or, in
> C, by violation of a "shall" outside a constraint).
 
For a human being, the additional sentence makes a difference, simply
because it is there: it means that the writer had a reason to write it,
and such writer's intent is part of the message that matters to a human
reader.
 
More specifically:
 
In C, the additional sentence actually poses a distinctive
characterization of the code that qualifies for undefined behavior, i.e.
"nonportable or erroneus" code, which is something else than saying
"anything that is not explicitly defined here". Now, the problem is that
the C definition actually redirects to a definition of "nonportable" and
(more relevantly) "erroneous", so a machine reader might trigger an
"undefined reference" error and stop parsing.
A language lawyer might interpret the wording as implying that anything
that is not explicitly defined is considered "nonportable" or
"erroneous", but that's an interpretation which is still to be proven to
hold in court, since the other party's lawyer might interpret the same
wording as UB being <<anything that is "nonportable" or "erroneous"
/and/ is not covered by this standard's requirements>>
 
Schematically, one might think of the entire set of possible source code
to be validated against the standard, and divide it into the subsets:
1) Explicitly defined valid code (e.g. syntax of declarations)
2) Explicitly defined invalid code (e.g. constraint violations)
3) Code which is not explicitly defined by 1) and 2)
 
Ideally, for a perfect standard, subset 3) would be empty - i.e. to make
a machine reader happy. In practice, standards are (luckily) written by
humans, so there may be something left in subset 3). To me, the
additional sentence is intended to give a rationale to discriminate
which is which in this area.
That said, lawyers may still complain that a non-empty subset 3) leads
to ambiguity, and this may be a serious problem in court.
 
Pre-C++11 C++ apparently tried to address this potential ambiguity by
adding "such as", thus suggesting that the category of "nonportable" or
"erroneous" code is meant to be an example of code for which the
standard poses "no requirements".
The wording may appear to suggest that subset 3) is meant to be included
in subset 2), but the authors didn't feel brave enough to say this
explicitly, and left the categories of "nonportable" and "erroneous" in.
The fact is that, obviously, placing subset 3) into subset 2) poses a
heavy burden on the standard itself.
 
C++11-and-later C++ was actually brave enough to assert that anything
that is not explicitly defined in the standard is "undefined behavior",
which would just be a self-identity assertion if it weren't for the note
that clarifies that UB is a very Bad Thing™, unless such behavior is
actually defined by the implementation.
 
The result is that the latest C++ definition of UB is so strong that it
suddenly raised the bar of the Standard's quality requirement by several
levels, thus opening the Pandora's box of countless examples of UB that
affect nowadays' C++, to the point of invalidating even sample code in
Bjarne's TC++PL that has been valid since the beginning of time, and led
to cryptic additions to the standard itself (std::launder, anyone?)
This might be seen as a process of improvement of the language, but so
far this seems controversial.
RacingRabbit@watershipdown.co.uk: Oct 26 03:21PM

On Tue, 26 Oct 2021 10:43:09 -0400
>> return 0;
>> }
 
>You shouldn't get a bus error this time. Do you understand why?
 
Noooo! Really??
 
Have you actually read anything I wrote or are you just jumping on the
bandwagon of what others have said in order to try and sound clever?
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:22AM -0400

>> with read-only memory. Within the scope of an identifier that identifies
 
> No I'm not. The pointer will be pointing to a string literal in the program
> static text area which is usually non modifiable.
 
Yes, I discussed that fact, which is the real reason for the bus error
you saw. It was not because you used * rather than [] in your
declaration of str.
 
>> Exception 1: it's not permitted to declare functions that take arrays as
>> arguments,
 
> Since when?
 
Since K&R C. As explained below, the following is NOT a counter example.
 
 
> void func(int a[2][3])
> {
> printf("%d\n",a[1][2]);
 
"A declaration of a parameter as "array of type" shall be adjusted to
"qualified pointer to type", where the type qualifiers (if any) are
those specified within the [ and ] of the array type derivation."
(6.7.63.p6).
There's an easy way you can test this. Declare func a second time, as
follows:
 
void func(int (*a)[3]);
 
Such redeclaration is permitted only if the new declaration is
compatible with the previous one. The "adjustment" described above makes
your declaration identical to the second one.
 
 
> int a[2][3];
> a[1][2] = 123;
> func(a);
 
Appearances to the contrary notwithstanding, that code does NOT pass the
entire array a to func(). That's because:
 
"Except when it is the operand of the sizeof operator, or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type "array of type" is converted to an expression
with type "pointer to type" that points to the initial element of the
array object and is not an lvalue." (6.3.2p3).
 
In the expression func(a), "a" is not the operand of the sizeof operator
or the unary & operator, and it is certainly not a string literal.
Therefore, a gets converted to &a[0]. Try it, add the following line to
your program:
 
func(&a[0]);
 
It won't be diagnosed as an error, because &a[0] is a pointer to an
array of 3 ints, which precisely what the first argument of func() has
been declared to be (after the adjustments described above). It will
simply result in a second printing of "123".
 
 
> }
> fenris$ cc t.c; a.out
> 123
 
Neither of these features are new, they both date back to K&R C.
RacingRabbit@watershipdown.co.uk: Oct 26 03:26PM

On Tue, 26 Oct 2021 15:55:38 +0100
 
>I actually listed the 7 compilers I tried it on, just at the point where
>you must have stopped reading.
 
>Oh, you mean you only tried it on one implementation?
 
Sorry, I have limited tolerance for smart asses so yes, I stopped reading.
They're all toy compilers apart from VC and I specifically was talking about
*nix and yes, these days that means gcc or clang.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:27AM -0400


>> This shows ABC the first time it's executed. The second time it shows
>> ZBC; the code has changed the string literal! Where the same literal iS
 
> I suggest you actually try running that code and see what happens.
 
The behavior of the code shown is undefined, and therefore very well
might be exactly as he described - you would need to know precisely
which compiler he used, on which platform, with which compiler options.
That is in fact common behavior for such code. He claims that he did
test it, and I know of no reason to disbelieve him.
RacingRabbit@watershipdown.co.uk: Oct 26 03:30PM

On Tue, 26 Oct 2021 11:22:18 -0400
 
>Yes, I discussed that fact, which is the real reason for the bus error
>you saw. It was not because you used * rather than [] in your
>declaration of str.
 
Hello, we speak English on this group. Do. You. Understand. It?
 
>>> arguments,
 
>> Since when?
 
>Since K&R C. As explained below, the following is NOT a counter example.
 
Thats exactly what it is. Too bad it made you look stupid.
 
>There's an easy way you can test this. Declare func a second time, as
>follows:
 
>void func(int (*a)[3]);
 
[hopeless effort at self justification]
 
You said arrays couldn't be declared as parameters. I showed you they could,
end of. What the compiler does with it under the hood is irrelevant.
 
tl;dr
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:52AM -0400

> On Tue, 26 Oct 2021 10:42:24 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
...
>> modifiable, but that's not just because of the "*", it's because str has
>> been initialized to point at the first character of a string literal. It
 
> So you disagree with what I said then say exactly the same thing yourself.
 
You said that "[] means modifyable, * means read only in every
C implementation I've ever used."
 
That is false.
 
What I said corresponds to the following examples:
 
char array1[] = "modifiable";
const char array2[] = "optionally read only";
char *pointer1 = array1;
const char *pointer2 = array1;
 
array1[0] = 'u'; // permitted
array2[0] = 'u'; // constraint violation
*pointer1 = 'u'; // permitted
*pointer2 = 'u'; // constraint violation
 
pointer1 = "optionally read only"; // permitted
*pointer1 = 'u'; // undefined behavior
pointer2 = array2;
*pointer2 = 'u'; // Still a constraint violation.
 
Despite both of them being declared with [], and therefore according to
you both being modifiable, array1 is modifiable, while array2 may be
placed in read-only memory - but it doesn't have to be.
 
Despite being declared with *, and therefore according to you being
read-only, pointer1 points at modifiable memory the first time it is
dereferenced, and points at memory that could be read-only the second
time it is dereferenced.
Despite being declared with *, pointer2 differs from pointer 1 in that
it is always a constraint violation to write through it, regardless of
whether or not it points at read-only memory.
Despite being both declared with *, and therefore according to you being
read-only, pointer1 and pointer2 are themselves modifiable, as shown by
the fact that I changed both of their values.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 12:23PM -0400

> On Tue, 26 Oct 2021 11:22:18 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
...
>> There's an easy way you can test this. Declare func a second time, as
>> follows:
 
>> void func(int (*a)[3]);
 
Did you try inserting such a line? What were the results?
 
> [hopeless effort at self justification]
 
> You said arrays couldn't be declared as parameters.
 
No, I said "it's not permitted to declare functions that take arrays as
arguments, but it is permitted to declare a function parameter as if it
were an array."
 
Such a declaration does NOT declare the parameter to be an array, it
declares it to be a pointer. You've retained my citation of the part of
the standard that says so above. Here's a complete compilable program
demonstrating that rule:
 
#include <stdio.h>
 
static void func(int a[2][3])
{
printf("%s\n",
_Generic(a, int[2][3]: "array", int(*)[3]: "pointer"));
}
 
int main(void)
{
int a[2][3];
func(a);
}
 
When I run that program, it says "pointer". What do you get when you run it?
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 09:49AM -0700

> On 26/10/2021 14:29, Ben Bacarisse wrote:
>> Bart <bc@freeuk.com> writes:
[...]
>> permitted in C++.
 
> I tried it in C++ before posting (as I'd thought that "ABC" would have
> type const char*) but it seemed to work. (Using -Wall -std=c++14.)
 
And you didn't bother to mention the diagnostic? I get
warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
And of course with "-pedantic-errors" it becomes a fatal error.
 
Did you not get a diagnostic? It's not all that interesting to see what
you can get away with by ignoring warnings.
 
> I'm writing about what is typically observed.
 
What I typically observe is that skilled programmers pay attention to
warnings and do not attempt to modify string literals.
 
> got round to it yet.
 
> It is surprising that a big compiler like MSVC doesn't do so either,
> but apparently that's only done when optimising; rather odd.)
 
My quick experiment with MSVC 2017 does not confirm that.
char *s = "ABC";
gives a fatal error in C++. It compiles in C (as expected), but
attempting to modify the literal causes a run-time crash.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 12:51PM -0400

On 10/26/21 12:23 PM, James Kuyper wrote:
...
> {
> printf("%s\n",
> _Generic(a, int[2][3]: "array", int(*)[3]: "pointer"));]]][
 
Here's another test you can perform. If that declaration declares a to
be an array, the following assignment statement, inserted in the body of
func(), should be a constraint violation:
 
int b[4][3];
a = b;
 
The left side of an assignment cannot have array type. On my system,
those lines compiled without generating any diagnostics.
 
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 10:22AM -0700

>>abysmal understanding of C, while believing you understand it better
>>than others.
 
> Says the preening fool.
 
James is not a "preening fool". He's right.
 
You have joined a forum many of whose participants are experts on the C
programming language. You have made a number of incorrect statements
about C, and you have shown an inappropriately condescending attitude
while doing so.
 
This is a great place to learn about C, and I sincerely hope you'll take
advantage of the opportunity. My advice is to express less certainty
about the statements you make, engage in discussion, and stop insulting
people.
 
>>modifiable, but that's not just because of the "*", it's because str has
>>been initialized to point at the first character of a string literal. It
 
> So you disagree with what I said then say exactly the same thing yourself.
 
No, that's not what he did. The array is read-only because it's a
string literal. You didn't say that.
 
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 10:27AM -0700

Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
[...]
> advantage of the opportunity. My advice is to express less certainty
> about the statements you make, engage in discussion, and stop insulting
> people.
 
Sorry, I didn't notice which newsgroup I was in. C++, not C. (The
rest of what I wrote stands.)
 
[...]
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Bart <bc@freeuk.com>: Oct 26 06:38PM +0100

On 26/10/2021 17:49, Keith Thompson wrote:
> And of course with "-pedantic-errors" it becomes a fatal error.
 
> Did you not get a diagnostic? It's not all that interesting to see what
> you can get away with by ignoring warnings.
 
I used rextester.com, which uses the default options I used. There were
no diagnostics.
 
Maybe I could have tested half a dozen more C++ compilers, but they're
thin on the ground on my machine.
 
 
>> I'm writing about what is typically observed.
 
> What I typically observe is that skilled programmers pay attention to
> warnings and do not attempt to modify string literals.
 
In general a compiler is not able to warn about the latter, and a
programmer may not know that a pointer passed via a function for example
points into readonly memory. Or out-of-bounds memory. Or contains NULL
or other invalid memory address.
 
It is however useful to know what might TYPICALLY happen if you do try
and write into a string literal.
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 02:06PM -0400

On 10/26/21 1:27 PM, Keith Thompson wrote:
>> people.
 
> Sorry, I didn't notice which newsgroup I was in. C++, not C. (The
> rest of what I wrote stands.)
 
Even though this is comp.std.c++, and the original message was about
C++, this sub-thread has turned into a discussion about C. However,
everything we're saying about C is true of C++ as well (with some minor
subtle differences), and everything he's saying incorrectly about C is
incorrect for C++, too. The biggest difference in C++ would be that
_Generic() is not supported, but typeinfo() is, which would actually be
a more convenient of proving the truth of what we're saying.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 11:20AM -0700

>> you can get away with by ignoring warnings.
 
> I used rextester.com, which uses the default options I used. There
> were no diagnostics.
 
Yes, there were. rextester.com didn't show them to you because you
didn't enable the "Show compiler warnings" checkbox.
 
> Maybe I could have tested half a dozen more C++ compilers, but they're
> thin on the ground on my machine.
 
>>> I'm writing about what is typically observed.
 
Any C++ compiler that does not issue a diagnostic for
 
char* s = "ABC";
 
is non-conforming. I'm skeptical that there are very many C++ compilers
out there that fail to do this when invoked properly. (C does not
require a diagnostic, which makes it important to remember to add
"const".)
 
> programmer may not know that a pointer passed via a function for
> example points into readonly memory. Or out-of-bounds memory. Or
> contains NULL or other invalid memory address.
 
In C++, it's difficult to even attempt to modify a string literal
without either triggering a required diagnostic or explicitly doing
something to override const. (It's easier in C, unfortunately.)
 
> It is however useful to know what might TYPICALLY happen if you do try
> and write into a string literal.
 
Agreed. What typically happens in C++ is that you'll get a diagnostic
before you even try to modify a string literal, since C++ string
literals are const. What typically happens in C is that the program
crashes. There are C compilers that don't put string literals in
read-only memory (I've confirmed that tcc doesn't), but as far as I
known none of them are in widespread use.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 26 11:20AM -0700

On 10/25/2021 12:45 PM, Chris M. Thomasson wrote:
> self, I will get a nice warning. Its basically a habit of mine. 'self'
> is akin to the this pointer in C++.
 
> Oh well... ;^)
 
See the deliberate mistake in here? Besides the foo_compute function
returning int typo, argh!... Anyway, here is a program:
______________________________
#include <stdio.h>
 
 
struct foo
{
unsigned int a;
};
 
 
void
foo_init(
struct foo* const self,
unsigned int a
){
self->a = a;
}
 
 
unsigned int
foo_compute(
struct foo const* const self,
unsigned int a
){
return self->a *= a + 123;
}
 
int main()
{
struct foo foo;
 
foo_init(&foo, 42);
 
unsigned int foobar = foo_compute(&foo, 42);
 
printf("foobar = %u\n", foobar);
 
return 0;
}
______________________________
 
Does not compile... GOOD! Change foo_compute to:
 
______________________________
unsigned int
foo_compute(
struct foo* const self,
unsigned int a
){
return self->a *= a + 123;
}
______________________________
 
and it does compile! So, const has it's uses, indeed.
 
;^)
James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 02:34PM -0400

On 10/26/21 12:23 PM, James Kuyper wrote:
...
> func(a);
> }
 
> When I run that program, it says "pointer". What do you get when you run it?
 
Unfortunately, that doesn't prove what I intended it to prove, because
even if a were an array, it would have been converted to a pointer when
passed to _Generic. That problem is not too difficult to work around, I
just have to use the '&' operator:
 
#include <stdio.h>
 
#define ARR_PTR(x) _Generic(&x, \
int(*)[2][3]: "array", \
int(**)[3]: "pointer", \
default: "other")
 
static void func(int a[2][3])
{
int b[2][3];
int (*c)[3];
printf("a:%s\n", ARR_PTR(a));
printf("b:%s\n", ARR_PTR(b));
printf("c:%s\n", ARR_PTR(c));
}
 
int main(void)
{
int a[2][3];
func(a);
}
 
I get the following output:
a:pointer
b:array
c:pointer
 
What do you get?
Bart <bc@freeuk.com>: Oct 26 08:32PM +0100

On 26/10/2021 19:20, Keith Thompson wrote:
>> were no diagnostics.
 
> Yes, there were. rextester.com didn't show them to you because you
> didn't enable the "Show compiler warnings" checkbox.
 
How about that? A professional-looking site, which, by default, enables
warnings for all those compilers and at the same time, by default,
chooses to hide those warnings!
Bart <bc@freeuk.com>: Oct 26 08:35PM +0100


> Sorry, I have limited tolerance for smart asses
 
Funny, that, so do I! So I'll leave you to it.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 26 12:57PM -0700

On 10/26/2021 11:34 AM, James Kuyper wrote:
> b:array
> c:pointer
 
> What do you get?
 
Fwiw, I get the same:
 
a:pointer
b:array
c:pointer
 
:^)
David Brown <david.brown@hesbynett.no>: Oct 26 10:18PM +0200

On 26/10/2021 21:32, Bart wrote:
 
> How about that? A professional-looking site, which, by default, enables
> warnings for all those compilers and at the same time, by default,
> chooses to hide those warnings!
 
When it comes to websites, "professional-looking" is not a good
indication of quality. I can't say much about that website, as I have
no experience with it, but any professional programmer who doesn't
enable warnings and pay attention to them should be looking for another
career. (Of course the exact choice of warnings, and appropriate ways
to handle them can vary by programmer style, project, and other factors.
Hiding them all, however, is never appropriate.)
 
I recommend <https://gotbolt.org> as having a wide selection of
compilers, and showing generated code in a helpful format. (I haven't
made a survey of alternatives and would be happy to hear of comparisons
if someone has a suggestion that is better than godbolt.)
David Brown <david.brown@hesbynett.no>: Oct 26 10:32PM +0200


> Noooo! Really??
 
> Have you actually read anything I wrote or are you just jumping on the
> bandwagon of what others have said in order to try and sound clever?
 
Rabbit, I believe you are missing a few key points here. James is not
trying to /sound/ clever - he /is/ clever. He is one of the top people
in this group in terms of his knowledge and experience of C and C++, his
accuracy in his explanations, and his patience in helping people.
(There are others here with a similar level of respect and reputation,
whom you have also insulted and disregarded.)
 
A second key point is that you are wrong about almost everything you
have been writing in this group - so wrong, that you don't even
understand the question.
 
You'd do well to stop being such an annoying little brat and listen to
the people who are spending time and effort trying to help you
understand the language a little better.
 
(And yes, I know you'll respond to this with insults - I'm old enough
not to be bothered about what some silly teenager thinks of me. But I
am also naïve enough to think that not even you are beyond hope.)
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 25 11:11AM -0700

> program construct or of erroneous data" actually relegates the
> language at the mercy of language lawyers, and led to the UB bloat
> that affects C++ nowadays.
[...]
 
I don't see how the omission of "upon use of a nonportable or erroneous
program construct or of erroneous data" in the C++ standard makes any
real difference.
 
C definition, all standard editions:
behavior, upon use of a nonportable or erroneous program construct
or of erroneous data, for which this International Standard imposes
no requirements
 
C++ definition, before C++11:
behavior, such as might arise upon use of an erroneous program
construct or erroneous data, for which this International Standard
imposes no requirement
 
C++ definition, C++11 and later:
behavior for which this International Standard imposes no requirements
 
In all cases, "undefined behavior" is determined either by an explicit
statement or by the omission of any definition of the behavior (or, in
C, by violation of a "shall" outside a constraint).
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Lynn McGuire <lynnmcguire5@gmail.com>: Oct 26 03:55PM -0500

"C++ Smart Pointers and Arrays" by Bartlomiej Filipek
https://www.cppstories.com/2021/smartptr-array/
 
"Smart pointers are very versatile and can hold pointers not only to
single instances but also to arrays. Is that only a theoretical use
case? or maybe they might be handy in some cases? Let's have a look."
 
Lynn
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.