Author Topic: C data len  (Read 3617 times)

0 Members and 1 Guest are viewing this topic.

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 151
  • Country: us
Re: C data len
« Reply #25 on: June 03, 2022, 03:41:03 am »
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.

What exactly do you refer to as "non-standard" here?
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5835
  • Country: es
Re: C data len
« Reply #26 on: June 03, 2022, 08:19:36 am »
Aha, nice to know. Anyways I always used defines for that  :-+
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4067
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C data len
« Reply #27 on: June 03, 2022, 01:35:08 pm »
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.

What exactly do you refer to as "non-standard" here?
Technically const int size = 50; isn't an "Integer constant expression" valid for use in the array declarator. But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value. After all, there is a valid integer constant expression literal being used, but just one reference away.
Then when you run the compiler with strict rules by specifying the standard it should follow, it says that it can't allow it. Which is technically correct, the best kind of correct.  :P

C is amazing, but it also is made by humans, so there will be corner cases, also extensions!.
« Last Edit: June 03, 2022, 01:39:03 pm by Jeroen3 »
 
The following users thanked this post: DiTBho

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 151
  • Country: us
Re: C data len
« Reply #28 on: June 03, 2022, 07:32:32 pm »
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.

What exactly do you refer to as "non-standard" here?
Technically const int size = 50; isn't an "Integer constant expression" valid for use in the array declarator.

True. In C it is not an Integer Constant Expression, in C++ it is an Integer Constant Expression.

But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value.

Um... Some C compilers allow it because they support VLA. An array with const int size is perfectly standard in C, as long as it is recognized as a VLA by the compiler and behaves as a VLA afterwards. Nothing non-standard about it.

After all, there is a valid integer constant expression literal being used, but just one reference away.

Not really. They simply treat it as a VLA. Basically, they ignore the const, they don't care about the constant expression hiding behind the name.

Then when you run the compiler with strict rules by specifying the standard it should follow, it says that it can't allow it. Which is technically correct, the best kind of correct.  :P

If you specify a pre-C99 standard, then of course. There was no VLA before C99.
« Last Edit: June 03, 2022, 07:35:01 pm by TheCalligrapher »
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #29 on: June 03, 2022, 08:57:46 pm »
But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value.

Um... Some C compilers allow it because they support VLA. An array with const int size is perfectly standard in C, as long as it is recognized as a VLA by the compiler and behaves as a VLA afterwards. Nothing non-standard about it.

Yep. Seems it has a hard time sinking in even though we said it several times already. ::)
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1714
  • Country: se
Re: C data len
« Reply #30 on: June 03, 2022, 09:43:49 pm »
Well, I disagree about a static storage duration array declared with a const int as dimension (or some equivalent expression) being a VLA in any way.

From the C standard perspective, it's not: static storage duration VLA being explicitly forbidden by the standard it's a non-entity.

OTOH, from an extension point of view, the array will have a constant, non changeable size, so no VLA semantic in any way.

On the gripping hand, I would rather surmise that the compilers allowing such construct are not relaxing VLA constraints, but rather taking advantage of paragraph 10 of ch 6.6 Constant Expressions:
Quote from: mon livre de chevet
An implementation may accept other forms of constant expressions.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #31 on: June 04, 2022, 09:53:51 am »
Sometimes, it's like talking with a lawyer  :o :o :o

You don't understand legalese, but you hope that paying someone who talks strangely solves your problems somehow.
« Last Edit: June 04, 2022, 12:21:55 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: newbrain

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 3999
  • Country: nz
Re: C data len
« Reply #32 on: June 04, 2022, 11:47:51 am »
On the gripping hand, I would rather surmise that the compilers allowing such construct are not relaxing VLA constraints, but rather taking advantage of paragraph 10 of ch 6.6 Constant Expressions:
Quote from: mon livre de chevet
An implementation may accept other forms of constant expressions.

So mote it be.

 
The following users thanked this post: newbrain

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #33 on: June 04, 2022, 06:09:27 pm »
Well, I disagree about a static storage duration array declared with a const int as dimension (or some equivalent expression) being a VLA in any way.

And as often, it's running in circles. ;D

As was noted early in the thread, with the OP's example, there was no way it could have been anything else than VLAs IMO, since 1/ the arrays were not qualified static and 2/ even if context was not given, as I mentioned earlier, it couldn't have been in file scope (so arrays declared as global variables), because the OP mentioned that it would compile with GCC, and no version of GCC I tried (but sure haven't tried them all) supports that.

So yes, sure, as I also said earlier, in "file scope", this construct is illegal in std C, and if some compiler accepts it, then it sure must be as an extension. But I have yet to find a compiler that does (and again, the little the OP gave us doesn't really point us to that case). Could you point me to one? Or did I miss something with GCC?
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1714
  • Country: se
Re: C data len
« Reply #34 on: June 04, 2022, 07:14:34 pm »
I am not disagreeing with you - if not on some fine points, brought up just to gently mock DiTBho  >:D!

As for the compiler, clang will warn you, but still compile that code, unless one uses -Werror.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #35 on: June 04, 2022, 07:25:49 pm »
mentioned that it would compile with GCC

I tried the original code with Gcc v4.1.2 on a PowerPC-7410 machine, got compiled and worked correctly  :o :o :o
A patch may have been applied to Gcc, I cannot verify it.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #36 on: June 04, 2022, 07:41:56 pm »
mentioned that it would compile with GCC

I tried the original code with Gcc v4.1.2 on a PowerPC-7410 machine, got compiled and worked correctly  :o :o :o
A patch may have been applied to Gcc, I cannot verify it.

So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)

GCC's default behavior keeps changing from version to version, so some extensions may have been added/removed/enabled by default or not/ depending on version.
The only way of ensuring something relatively consistent is to pass a 'std=' option to GCC. (Not completely foolproof, but better than leaving the default behavior.)

So anyway, I suggest not using variables for declaring fixed-size arrays in C, even if said variable is qualified const. It may "compile" depending on context and compiler extensions, but it's not guaranteed, not necessarily standard except in local context, and in this latter case, will yield a VLA that you didn't necessarily expect. It may look nicer than macros, but it's just not the right way of doing it in std C (unless in local context as auto variables and you really want a VLA.)

People not liking macros just need to get over it when writing C. Insisting on avoiding them will usually lead to writing non-standard C, and/or use hard-coded values everywhere, and/or duplicate code, making your code a hell to maintain. Just MHO.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #37 on: June 04, 2022, 07:48:17 pm »
To give you the point, I found the original code on a PowerMac-clone running GNU/Linux ~2007. I also found a couple of programs written by a dude to query the installed PCI-SCSI-HBA.

Interesting code, but it's written, as usual, in a very dirty way, and I am going to study and rewrite from scratch in order to integrate its functionalities into my last toil.

as an extension

On the GNU/Linux (ext2, OMG) partition there is a Gcc v4.1.2 compiler, enabled_languages are {C, C++ }.
When the 'Makefile' invokes 'Gcc', 'CC1' is perfectly able to compile the dirty code, even if there are no explicit Cflags passed to the compiler.

is it implicit C99? Or what? Dunno :-//

How can I check if it has been patched and / or compiled with extensions?  :o :o :o
« Last Edit: June 04, 2022, 08:34:20 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #38 on: June 04, 2022, 08:10:04 pm »
People not liking macros just need to get over it when writing C. Insisting on avoiding them will usually lead to writing non-standard C

I think this refers to what I said in the other topic, when I said that I don't like Macros  :o :o :o

Well, Macros are the result of a #define statement, and the pre-processor is a feature of C.
Therefore, technically, the following is a Macro:
Code: [Select]
#define array_SIZE 1024
uint8_t array[ array_SIZE ];
however, it's the only exception to what I suggested to avoid in the other topic and I still strongly suggest: to avoid all other (ab)uses of the pre-processor.

That is when and why:
1) affect things you don't realize, and you can not debug
2) expansion can lead to strange side effects
3) your code gets deranged-replacements, and your CC/ICE leads to strange error WTF?-messages
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #39 on: June 04, 2022, 08:32:01 pm »
So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)

In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
Code: [Select]
    const unsigned int  data_size = 32;
    unsigned char data[data_size];
    const unsigned int  sense_len = 256;
    unsigned char sense[sense_len];
as global definition, outside a function.

It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.

Great! But when I moved the code to AvogetCC, it didn't get compiled at all. The compiler doesn't understand VLAs (there are 21 points to be rewritten), and doesn't like 'const', and this is also a problem for my ICE since I massively need to debug/interact with the hardware.

I need to use AvogetCC + ICE on a industrial PPC machine with the same HBA chip soldered on the Motherboard but exposed to a simpler bus, I am doing it for wild hacking reasons (full reverse engineering of the used SCSI queries), I cannot use Gcc because it's not a GNU-supported machine (NetBSD .. maybe on day it will run, but at the moment the kernel crashes), hence here we go rewriting everything.

Problem solved two days ago, just ... still questions in my head + tons of WTF?!?  :o :o :o
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C data len
« Reply #40 on: June 04, 2022, 08:57:16 pm »
In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
Code: [Select]
    const unsigned int  data_size = 32;
    unsigned char data[data_size];
    const unsigned int  sense_len = 256;
    unsigned char sense[sense_len];
as global definition, outside a function.

It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.

This is very confusing, because see here:

https://godbolt.org/z/ernG9531s

It really didn't ought to compile.
 
The following users thanked this post: newbrain

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #41 on: June 04, 2022, 08:58:11 pm »
So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)

In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
Code: [Select]
    const unsigned int  data_size = 32;
    unsigned char data[data_size];
    const unsigned int  sense_len = 256;
    unsigned char sense[sense_len];
as global definition, outside a function.

OK, so indeed at what is called "file scope".

It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.

I don't get how. Tried is with GCC 4.1.2 on godbolt, we get the same error "error: variably modified 'data' at file scope".
Possibly the compiler you were using was patched or something. But with the official source code, it yields an error.

Great! But when I moved the code to AvogetCC, it didn't get compiled at all. The compiler doesn't understand VLAs (there are 21 points to be rewritten), and doesn't like 'const',

If it doesn't "understand" VLAs, then it's just not compliant with C99. That's the only thing that will tell you if VLAs are supported. (Note that with later versions of the C std, VLAs became optional IIRC. But from what I get, you seem to be using rather old tools, so the probability of your compilers not compliant with C99 is much higher than that of being compliant with later revisions of the std and making it default.)

That said, again in this global context ("file scope"), the above construct is NOT a VLA. It's nothing. It's just not allowed in C. Some compilers may allow it as an extension, but GCC does not, with all tests I've done with versions down to 4.1.2. (Or maybe it would require an extra option I'm not aware of.) So if yours does, either it was patched for this, or enabled some compiler option that I do not know.

 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #42 on: June 04, 2022, 10:25:19 pm »
Not easy on a 2022 portage because there is this constraint that doesn't allow you to easily compile anything <Gcc-v10
Code: [Select]
# 2022-05-28: GCC v9 and older no longer receive upstream support or fixes for bugs.
# Please switch to a newer GCC version using gcc-config.
# The lowest supported version of GCC is GCC 10.
<sys-devel/gcc-10
(plus, they removed all the building eclass support ... and, off course, the new ones are incompatible with the old one)
but, thanks to a combined chrooted-old-rootfs, I recreated gcc v4.1.2 on a modern Gentoo machine with all the old Gentoo patches

results:
Code: [Select]
gcc test.c -o test

Code: [Select]
gcc-v4.1.2, PPC7450, 32bit/BE
test.c:2: error: variably modified 'data' at file scope
test.c:4: error: variably modified 'sense' at file scope
Code: [Select]
gcc-v9.4.0, PPC7450, 32bit/BE
test.c:2:15: error: variably modified 'data' at file scope
    2 | unsigned char data[data_size];
      |               ^~~~
test.c:4:15: error: variably modified 'sense' at file scope
    4 | unsigned char sense[sense_len];
      |               ^~~~~

Perfect! So it doesn't compile unless you apply a special patch, which now I know, it was officially supported by neither GNU nor Gentoo.
Code: [Select]
/* test.c */
const unsigned int  data_size = 32;
unsigned char data[data_size];
const unsigned int  sense_len = 256;
unsigned char sense[sense_len];

int main()
{
   return 0;
}

Where did the patch come from? Who did applied it? And why? ... It's a mystery ...  :-//

Thanks guys!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1714
  • Country: se
Re: C data len
« Reply #43 on: June 04, 2022, 10:58:35 pm »
Quote
Note that with later versions of the C std, VLAs became optional IIRC.
Yes, in C11 the macro __STDC_NO_VLA__  is defined (to 1) to indicate that there's no support for VLA and VM types (types depending on a VLA, to simplify), see 6.10.8.3 Conditional feature macros:
Quote
[...]
__STDC_NO_VLA__ The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.

Note that this is going (probably) to change again in C23, where VM types will be mandatory, as well as VLA with allocated storage duration, i.e. a VLA one gets through setting a VLA pointer - a VM type - to an address returned by malloc(), and VLA syntax for function paramter (this last one is a good thing, if I understand the implications correctly).
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #44 on: June 04, 2022, 11:01:47 pm »
Code: [Select]
void foo()
{
    const unsigned int  data_size = 32;
    unsigned char       data[data_size];
    const unsigned int  sense_len = 256;
    unsigned char       sense[sense_len];
}

int main()
{
   foo();
   return 0;
}

for completeness, I repeated the test: this compiles on Gcc v4.1.2, doesn't compile on AvogetCC
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 3796
  • Country: gb
Re: C data len
« Reply #45 on: June 04, 2022, 11:07:04 pm »
Note that this is going (probably) to change again in C23, where VM types will be mandatory, as well as VLA with allocated storage duration

There are two modules in modern Firefox that require VLA; I didn't look at the code, but I am 100% sure because I remember a patch that didn't nothing but enable them with a define. Hope they don't mess too much, it's already a mess supporting Firefox, especially on ancient machines where you cannot always have the latest compier feature on hand.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #46 on: June 06, 2022, 07:44:15 pm »
Code: [Select]
void foo()
{
    const unsigned int  data_size = 32;
    unsigned char       data[data_size];
    const unsigned int  sense_len = 256;
    unsigned char       sense[sense_len];
}

int main()
{
   foo();
   return 0;
}

for completeness, I repeated the test: this compiles on Gcc v4.1.2, doesn't compile on AvogetCC

But in this context (local scope, auto), those are VLAs, so again, your AvogetCC is not C99-compliant, and that's it.

 
The following users thanked this post: newbrain, DiTBho

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14301
  • Country: fr
Re: C data len
« Reply #47 on: June 06, 2022, 07:46:02 pm »
Note that this is going (probably) to change again in C23, where VM types will be mandatory, as well as VLA with allocated storage duration

There are two modules in modern Firefox that require VLA; I didn't look at the code, but I am 100% sure because I remember a patch that didn't nothing but enable them with a define. Hope they don't mess too much, it's already a mess supporting Firefox, especially on ancient machines where you cannot always have the latest compier feature on hand.

Just because VLAs became optional in C11 doesn't mean that compilers will stop supporting them. It means they might. If that's convenient for them. Also, it doesn't mean they will stop supporting C99 either.

There's absolutely 0 chance IMHO that GCC or CLang would stop supporting VLAs even with newer revisions of the std, but even less chance they will stop supporting C99, so there will always be at least an option to force C99.

For more obscure compilers, all bets are off.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4067
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C data len
« Reply #48 on: June 07, 2022, 07:59:43 am »
You can always make your own VLA by recursion!

please dont
 
The following users thanked this post: newbrain, DiTBho


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf