Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > VLA question

Reply
Thread Tools

VLA question

 
 
Ike Naar
Guest
Posts: n/a
 
      06-27-2013
On 2013-06-27, ?? Tiib <(E-Mail Removed)> wrote:
> On Thursday, 27 June 2013 07:58:34 UTC+3, Ike Naar wrote:
>> On 2013-06-26, ?? Tiib <(E-Mail Removed)> wrote:
>> > Unless I misunderstand we are talking only of few idiomatic cases like
>> > 'malloc(sizeof(T))'. A custom preprocessor that adds redundant casts
>> > feels trivial to write.

>>
>> C++ has 'new T' which seems to be more idiomatic than 'malloc(sizeof(T)'.

>
> Indeed it is in C++ but not in C and we are discussing common subset.


Others have stated that C++ and C are different languages and I agree
with that. Though code written in the common subset is, technically,
C++, it is often non-idiomatic C++.
Many C-isms are considered bad style in C++.
 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      06-27-2013
On 27-Jun-13 07:28, James Kuyper wrote:
> On 06/26/2013 03:35 PM, Stephen Sprunk wrote:
>> IMHO, any code that relies on character literals being of type int
>> is _already_ broken, and the current mis-definition does nothing
>> but hide such bugs from the programmer, which is not worth
>> preserving.

>
> Given that the standard currently guarantees that they are of type
> 'int', I cannot agree with that assessment. However, that led me to
> think about precisely what kind of code you're talking about.
> Obviously, the value of (sizeof 'c') depends upon that assumption,
> but such expressions would only occur in code deliberately contrived
> to distinguish C from C++ according tot he current rules.


IMHO, anyone that uses such tricks to distinguish between C and C++,
rather than simply using #ifdef __cplusplus, deserves what they get.

> In C++, the type of a character literal can determine which operator
> overload is selected, which is why C++ made this change. There was
> no comparable reason in C, until the addition of _Generic() to
> C2011. However, _Generic() is very new and not widely supported, and
> as a result, not widely used. I doubt that you're talking about such
> code.


No.

> The value of a character literal will be same, whether it has type
> 'int' or type 'char', so long as char is signed, or is unsigned with
> CHAR_MAX <= INT_MAX. Only if CHAR_MAX > INT_MAX could it matter.
> Character literals that currently have a negative value would instead
> have a positive value greater than INT_MAX.


The only example I can envision a problem with is a character literal
that today is negative. IIRC, the conversion to char is well-defined in
that case. However, if character literals were char, it'd have a large
positive value. Storing in a char would still be fine, but storing in
an int would require a possibly-problematic conversion.

Is that the concern?

> Implementations where CHAR_MAX > INT_MAX are extremely rare,
> probably non-existent, but if one does exist, it could be fully
> conforming to the C standard. Such an implementation must have
> CHAR_MIN == 0, CHAR_BIT >= 16, and unless there's a lot of padding
> bits in an int, sizeof(int) == 1.


If we also assume that int has no padding bits, that doesn't seem
completely unreasonable, actually. There are probably DSPs like that.

The problem could be solved by the implementation defining plain char to
be signed, which is the only sane choice if a character literal can be
negative (even as an int) in the first place.

If all character literals are non-negative and plain char is unsigned,
then there is no problem making them char on such a system. That is
what a C++ implementation would have to do, and it would be insane for C
implementations for the same platform to differ.

> Conclusion: Code which depends upon the assumption that character
> literals have type 'int' (excluding cases involving sizeof or
> _Gerneric()) must do so in one of two basic ways:
>
> 1. Assuming that character literals never have a value greater than
> INT_MAX.
> 2. Assuming that character literals are never promoted to 'unsigned
> int'.
>
> Those assumptions could fail if character literals were changed to
> 'char', but only on implementations where CHAR_MAX > INT_MAX. Are
> you sure you want to claim that all such code is "broken"?


I'm still wrapping my head around your (excellent, BTW) analysis, but my
gut tells me that such code is indeed "broken". Perhaps if you could
come up with a concrete example of code that you think is non-broken but
would fail if character literals were char, rather than an abstract
argument?

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      06-27-2013
On 27-Jun-13 09:17, Eric Sosman wrote:
> On 6/26/2013 6:17 PM, Öö Tiib wrote:
>> Unless I misunderstand we are talking only of few idiomatic cases
>> like 'malloc(sizeof(T))'. A custom preprocessor that adds redundant
>> casts feels trivial to write.

>
> What's the correct cast to insert in
>
> ptr->link = malloc(sizeof *ptr->link);
>
> ?


ptr->link = (typeof *ptr->link)malloc(sizeof *ptr-link);



S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      06-27-2013
On 27-Jun-13 11:20, Stephen Sprunk wrote:
> On 27-Jun-13 09:17, Eric Sosman wrote:
>> On 6/26/2013 6:17 PM, Öö Tiib wrote:
>>> Unless I misunderstand we are talking only of few idiomatic cases
>>> like 'malloc(sizeof(T))'. A custom preprocessor that adds redundant
>>> casts feels trivial to write.

>>
>> What's the correct cast to insert in
>>
>> ptr->link = malloc(sizeof *ptr->link);
>>
>> ?

>
> ptr->link = (typeof *ptr->link)malloc(sizeof *ptr-link);


*sigh* I really need to stop hitting "Send" before proofreading--or
quit depending on the compiler to catch errors. That should be:

ptr->link = (typeof ptr->link)malloc(sizeof *ptr-link);

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-27-2013
Stephen Sprunk <(E-Mail Removed)> writes:
> On 27-Jun-13 07:28, James Kuyper wrote:

[...]
>> The value of a character literal will be same, whether it has type
>> 'int' or type 'char', so long as char is signed, or is unsigned with
>> CHAR_MAX <= INT_MAX. Only if CHAR_MAX > INT_MAX could it matter.
>> Character literals that currently have a negative value would instead
>> have a positive value greater than INT_MAX.

>
> The only example I can envision a problem with is a character literal
> that today is negative. IIRC, the conversion to char is well-defined in
> that case. However, if character literals were char, it'd have a large
> positive value. Storing in a char would still be fine, but storing in
> an int would require a possibly-problematic conversion.


That doesn't seem right. A character constant that has a negative value
today (because plain char is a signed type) would still have a negative
value if character constants were of type char. It would just be a
negative value of type char.

Here's a demonstration:

#include <stdio.h>
int main(void) {
printf("'\\x80' = %d\n", '\x80');
return 0;
}

On a system with CHAR_BIT==8, with plain char being signed, I get:

'\x80' = -128

If '\x80' were of type char, its value would be (char)-128, which would
be promoted to int (because printf is variadic), giving the same result.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      06-27-2013
On 06/27/2013 01:44 PM, Keith Thompson wrote:
> Stephen Sprunk <(E-Mail Removed)> writes:
>> On 27-Jun-13 07:28, James Kuyper wrote:

> [...]
>>> The value of a character literal will be same, whether it has type
>>> 'int' or type 'char', so long as char is signed, or is unsigned with
>>> CHAR_MAX <= INT_MAX. Only if CHAR_MAX > INT_MAX could it matter.
>>> Character literals that currently have a negative value would instead
>>> have a positive value greater than INT_MAX.

>>
>> The only example I can envision a problem with is a character literal
>> that today is negative. IIRC, the conversion to char is well-defined in
>> that case. However, if character literals were char, it'd have a large
>> positive value. Storing in a char would still be fine, but storing in
>> an int would require a possibly-problematic conversion.

>
> That doesn't seem right. A character constant that has a negative value
> today (because plain char is a signed type) would still have a negative
> value if character constants were of type char. It would just be a
> negative value of type char.
>
> Here's a demonstration:
>
> #include <stdio.h>
> int main(void) {
> printf("'\\x80' = %d\n", '\x80');
> return 0;
> }
>
> On a system with CHAR_BIT==8, with plain char being signed, I get:
>
> '\x80' = -128
>
> If '\x80' were of type char, its value would be (char)-128, which would
> be promoted to int (because printf is variadic), giving the same result.


As I indicated above, the problem I described arises only on
implementations where CHAR_MAX > INT_MAX. If CHAR_BIT==8, then you can't
have been testing on such a system.

 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      06-27-2013
On 2013-06-27, James Kuyper <(E-Mail Removed)> wrote:
> As I indicated above, the problem I described arises only on
> implementations where CHAR_MAX > INT_MAX. If CHAR_BIT==8, then you can't
> have been testing on such a system.


I was about to say "hang on, how can that happen, int must be at least
as wide as char", but of course, it can happen if CHAR_MAX == UCHAR_MAX.

-s
--
Copyright 2013, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
Autism Speaks does not speak for me. http://autisticadvocacy.org/
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      06-27-2013
On 06/27/2013 02:41 PM, Seebs wrote:
> On 2013-06-27, James Kuyper <(E-Mail Removed)> wrote:
>> As I indicated above, the problem I described arises only on
>> implementations where CHAR_MAX > INT_MAX. If CHAR_BIT==8, then you can't
>> have been testing on such a system.

>
> I was about to say "hang on, how can that happen, int must be at least
> as wide as char", but of course, it can happen if CHAR_MAX == UCHAR_MAX.


Right - as I mentioned earlier, CHAR_MAX > INT_MAX implies that CHAR_MIN
== 0.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-27-2013
James Kuyper <(E-Mail Removed)> writes:
> On 06/27/2013 02:41 PM, Seebs wrote:
>> On 2013-06-27, James Kuyper <(E-Mail Removed)> wrote:
>>> As I indicated above, the problem I described arises only on
>>> implementations where CHAR_MAX > INT_MAX. If CHAR_BIT==8, then you can't
>>> have been testing on such a system.

>>
>> I was about to say "hang on, how can that happen, int must be at least
>> as wide as char", but of course, it can happen if CHAR_MAX == UCHAR_MAX.

>
> Right - as I mentioned earlier, CHAR_MAX > INT_MAX implies that CHAR_MIN
> == 0.


Suppose CHAR_BIT==32, CHAR_MIN==-2**31, CHAR_MAX==2**31-1,
sizeof(int)==1, and int has one padding bit, so INT_MAX==2**30-1.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      06-27-2013
On 06/27/2013 06:06 PM, Keith Thompson wrote:
> James Kuyper <(E-Mail Removed)> writes:
>> On 06/27/2013 02:41 PM, Seebs wrote:
>>> On 2013-06-27, James Kuyper <(E-Mail Removed)> wrote:
>>>> As I indicated above, the problem I described arises only on
>>>> implementations where CHAR_MAX > INT_MAX. If CHAR_BIT==8, then you can't
>>>> have been testing on such a system.
>>>
>>> I was about to say "hang on, how can that happen, int must be at least
>>> as wide as char", but of course, it can happen if CHAR_MAX == UCHAR_MAX.

>>
>> Right - as I mentioned earlier, CHAR_MAX > INT_MAX implies that CHAR_MIN
>> == 0.

>
> Suppose CHAR_BIT==32, CHAR_MIN==-2**31, CHAR_MAX==2**31-1,
> sizeof(int)==1, and int has one padding bit, so INT_MAX==2**30-1.


You're right - I reached that conclusion so many years ago that I forgot
the assumptions I relied upon to reach it. I was thinking of the minimal
case where CHAR_MAX is as small as possible while still being greater
than INT_MAX, in which case there's no room for padding bits. If you
move away from the minimal case, there is room for padding bits, and
then the argument breaks down. Of course, such implementations are even
less commonplace than the minimal case.

I'll have to review my earlier comments more carefully with that
correction in mind.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Routing Between Two VLA Ns Bob Simon Cisco 5 02-06-2007 01:15 AM
VLA Question pemo C Programming 8 02-24-2006 01:04 PM
support of C99 VLA in compilers Ben Hinkle C Programming 6 12-15-2005 02:08 PM
Compound literals and VLA's William Ahern C Programming 6 08-24-2005 05:40 AM
[C99] local VLA with dimension given by a global var? MackS C Programming 15 02-21-2005 07:59 PM



Advertisments