Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #89090 > unrolled thread

Re: efficient coding with literals and variables

Started byBartC <bc@freeuk.com>
First post2016-06-14 20:53 +0100
Last post2016-06-15 14:53 -0700
Articles 12 — 5 participants

Back to article view | Back to comp.lang.c

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: efficient coding with literals and variables BartC <bc@freeuk.com> - 2016-06-14 20:53 +0100
    Re: efficient coding with literals and variables David Brown <david.brown@hesbynett.no> - 2016-06-15 08:59 +0200
      Re: efficient coding with literals and variables Keith Thompson <kst-u@mib.org> - 2016-06-15 10:01 -0700
        Re: efficient coding with literals and variables David Brown <david.brown@hesbynett.no> - 2016-06-15 19:47 +0200
          Re: efficient coding with literals and variables Keith Thompson <kst-u@mib.org> - 2016-06-15 11:47 -0700
      Re: efficient coding with literals and variables Ike Naar <ike@iceland.freeshell.org> - 2016-06-15 21:23 +0000
        Re: efficient coding with literals and variables David Brown <david.brown@hesbynett.no> - 2016-06-15 23:53 +0200
          Re: efficient coding with literals and variables Ike Naar <ike@iceland.freeshell.org> - 2016-06-15 22:41 +0000
            Re: efficient coding with literals and variables "James R. Kuyper" <jameskuyper@verizon.net> - 2016-06-15 18:54 -0400
              Re: efficient coding with literals and variables Ike Naar <ike@iceland.freeshell.org> - 2016-06-16 05:41 +0000
            Re: efficient coding with literals and variables David Brown <david.brown@hesbynett.no> - 2016-06-16 09:12 +0200
        Re: efficient coding with literals and variables Keith Thompson <kst-u@mib.org> - 2016-06-15 14:53 -0700

#89090 — Re: efficient coding with literals and variables

FromBartC <bc@freeuk.com>
Date2016-06-14 20:53 +0100
SubjectRe: efficient coding with literals and variables
Message-ID<njpnbq$je8$1@dont-email.me>
On 14/06/2016 20:21, Stefan Ram wrote:
>   In my beginner's course, I have just introduced const
>   variables and show these two compound statements for
>   comparison:
>
> { int const money_owned_before = 100;
>   int const money_paid = 26;
>   int const money_remaining = money_owned_before - money_paid;
>   printf( "%d\n", money_remaining ); }
>
> { printf( "%d\n", 100 - 26 ); }
>
>   . A participant asked whether the first one was less
>   efficient, and I answered »no« - given today's optimizing
>   compilers. (I also /did/ explain that a »printf« usually
>   will take much more time than any of the calculations from
>   above.)
>
>   But is it possible that today there are custom compilers
>   (i.e., compilers not based on gcc or clang) for
>   special microcontrollers or embedded or small systems
>   that do not feature many optimizations?

Tiny C won't do the first optimisation (reducing the const ints to 74), 
but it will do the second (folding 100-26 to 74).

There are a few other small C compilers around, not necessarily for 
small systems, which may not optimise either. (The SDCC compiler posted 
about  recently is for small systems, but is not a small compiler.)

(I'm not sure I would bother either: if these are constant values known 
at compile time, then #define or enums are better ways of denoting a 
named constant.)

(BTW what's the purpose of the braces around the second printf? Because 
your code seems at serious risk of degenerating into Lisp!)

-- 
Bartc

[toc] | [next] | [standalone]


#89133

FromDavid Brown <david.brown@hesbynett.no>
Date2016-06-15 08:59 +0200
Message-ID<njqucm$1e9$1@dont-email.me>
In reply to#89090
On 14/06/16 21:53, BartC wrote:
> On 14/06/2016 20:21, Stefan Ram wrote:
>>   In my beginner's course, I have just introduced const
>>   variables and show these two compound statements for
>>   comparison:
>>
>> { int const money_owned_before = 100;
>>   int const money_paid = 26;
>>   int const money_remaining = money_owned_before - money_paid;

I think it is far nicer to put type qualifiers such as "const" or
"volatile" at the start of the declaration - "const int", not "int
const".  But that is personal opinion, and I'm not sure I can give a
better justification than "I think it is nicer or clearer".  If others
have better reasons for picking one way or the other, I'd be interested
to hear.

>>   printf( "%d\n", money_remaining ); }
>>
>> { printf( "%d\n", 100 - 26 ); }
>>
>>   . A participant asked whether the first one was less
>>   efficient, and I answered »no« - given today's optimizing
>>   compilers. (I also /did/ explain that a »printf« usually
>>   will take much more time than any of the calculations from
>>   above.)
>>
>>   But is it possible that today there are custom compilers
>>   (i.e., compilers not based on gcc or clang) for
>>   special microcontrollers or embedded or small systems
>>   that do not feature many optimizations?
> 
> Tiny C won't do the first optimisation (reducing the const ints to 74),
> but it will do the second (folding 100-26 to 74).
> 
> There are a few other small C compilers around, not necessarily for
> small systems, which may not optimise either. (The SDCC compiler posted
> about  recently is for small systems, but is not a small compiler.)
> 

There are still a few compilers in use that would fail to optimise these
const ints.  But they are increasingly rare or niche tools, such as
compilers for outdated microcontrollers that are still used for updates
to old systems.  Most compilers, not just gcc or clang (or other "big
names" like MSVC or icc) will handle these optimisations fine.

To a large extent, you can simply ignore such limited systems except to
tell your students that they do still exist.  Certainly you should not
teach or use poorer code style or older or limited constructs because
there are still a few limited compilers around (except as part of a
specific "dealing with legacy systems" lesson).

There is one major exception - if the compiler is called without
enabling optimisation.  Typically the compiler will then create the
const int data on the stack, and may or may not fold the constant
calculation.  But you should be teaching your students that they must
always use optimisation - this means that they can write their source
code in the best way, and let the compiler handle most of the details of
generating efficient object code.  (It is also essential for making full
use of the compiler's static error checking.)

> (I'm not sure I would bother either: if these are constant values known
> at compile time, then #define or enums are better ways of denoting a
> named constant.)

No, #define and enum are /not/ better ways of denoting named constants.
 They are sometimes the only way to get what you need, especially in C
(in C++, "const int" is more powerful than it is in plain C).  It's okay
to say that you /prefer/ to use #define or enum for named constants -
but don't make the mistake of thinking your preferences for an extremely
simple, limited and flat-structured language is "better" for other
people or other purposes.

> 
> (BTW what's the purpose of the braces around the second printf? Because
> your code seems at serious risk of degenerating into Lisp!)
> 

It is clearly a second example for comparison with the first.  Imagine
he had added "void test1(void)" before the first open brace, and "void
test2(void)" before the second one.

[toc] | [prev] | [next] | [standalone]


#89174

FromKeith Thompson <kst-u@mib.org>
Date2016-06-15 10:01 -0700
Message-ID<lnk2hqz8qh.fsf@kst-u.example.com>
In reply to#89133
David Brown <david.brown@hesbynett.no> writes:
> On 14/06/16 21:53, BartC wrote:
[...]
>> (I'm not sure I would bother either: if these are constant values known
>> at compile time, then #define or enums are better ways of denoting a
>> named constant.)
>
> No, #define and enum are /not/ better ways of denoting named constants.
>  They are sometimes the only way to get what you need, especially in C
> (in C++, "const int" is more powerful than it is in plain C).  It's okay
> to say that you /prefer/ to use #define or enum for named constants -
> but don't make the mistake of thinking your preferences for an extremely
> simple, limited and flat-structured language is "better" for other
> people or other purposes.

The problem with const is that it doesn't create a constant expression.
enum does (though it's limited to constants of type int).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [next] | [standalone]


#89177

FromDavid Brown <david.brown@hesbynett.no>
Date2016-06-15 19:47 +0200
Message-ID<njs4c3$dev$1@dont-email.me>
In reply to#89174
On 15/06/16 19:01, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 14/06/16 21:53, BartC wrote:
> [...]
>>> (I'm not sure I would bother either: if these are constant values known
>>> at compile time, then #define or enums are better ways of denoting a
>>> named constant.)
>>
>> No, #define and enum are /not/ better ways of denoting named constants.
>>   They are sometimes the only way to get what you need, especially in C
>> (in C++, "const int" is more powerful than it is in plain C).  It's okay
>> to say that you /prefer/ to use #define or enum for named constants -
>> but don't make the mistake of thinking your preferences for an extremely
>> simple, limited and flat-structured language is "better" for other
>> people or other purposes.
>
> The problem with const is that it doesn't create a constant expression.
> enum does (though it's limited to constants of type int).
>

Yes, and that is an annoying limitation (C++ improves on that) - which 
is why I said that #define and enum are "sometimes the only way to get 
what you need".  But in other aspects, "const" objects are better - in 
particular, they obey the scoping and parsing rules of C rather than the 
pre-processor, and they have a proper type (rather than being sort-of 
int, sort-of their own enumeration type for enums).

[toc] | [prev] | [next] | [standalone]


#89185

FromKeith Thompson <kst-u@mib.org>
Date2016-06-15 11:47 -0700
Message-ID<ln37oez3v4.fsf@kst-u.example.com>
In reply to#89177
David Brown <david.brown@hesbynett.no> writes:
> On 15/06/16 19:01, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 14/06/16 21:53, BartC wrote:
>> [...]
>>>> (I'm not sure I would bother either: if these are constant values known
>>>> at compile time, then #define or enums are better ways of denoting a
>>>> named constant.)
>>>
>>> No, #define and enum are /not/ better ways of denoting named constants.
>>>   They are sometimes the only way to get what you need, especially in C
>>> (in C++, "const int" is more powerful than it is in plain C).  It's okay
>>> to say that you /prefer/ to use #define or enum for named constants -
>>> but don't make the mistake of thinking your preferences for an extremely
>>> simple, limited and flat-structured language is "better" for other
>>> people or other purposes.
>>
>> The problem with const is that it doesn't create a constant expression.
>> enum does (though it's limited to constants of type int).
>
> Yes, and that is an annoying limitation (C++ improves on that) - which 
> is why I said that #define and enum are "sometimes the only way to get 
> what you need".  But in other aspects, "const" objects are better - in 
> particular, they obey the scoping and parsing rules of C rather than the 
> pre-processor, and they have a proper type (rather than being sort-of 
> int, sort-of their own enumeration type for enums).

Enumeration constants are not sort-of anything.  They're of type int.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [next] | [standalone]


#89210

FromIke Naar <ike@iceland.freeshell.org>
Date2016-06-15 21:23 +0000
Message-ID<slrn3vfsnm3hqh.i2o.ike@iceland.freeshell.org>
In reply to#89133
On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
> I think it is far nicer to put type qualifiers such as "const" or
> "volatile" at the start of the declaration - "const int", not "int
> const".  But that is personal opinion, and I'm not sure I can give a
> better justification than "I think it is nicer or clearer".  If others
> have better reasons for picking one way or the other, I'd be interested
> to hear.

The terminology used in the C standard documents is "integer constant",
not "constant integer".

[toc] | [prev] | [next] | [standalone]


#89217

FromDavid Brown <david.brown@hesbynett.no>
Date2016-06-15 23:53 +0200
Message-ID<njsio7$34q$1@dont-email.me>
In reply to#89210
On 15/06/16 23:23, Ike Naar wrote:
> On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
>> I think it is far nicer to put type qualifiers such as "const" or
>> "volatile" at the start of the declaration - "const int", not "int
>> const".  But that is personal opinion, and I'm not sure I can give a
>> better justification than "I think it is nicer or clearer".  If others
>> have better reasons for picking one way or the other, I'd be interested
>> to hear.
>
> The terminology used in the C standard documents is "integer constant",
> not "constant integer".
>

An "integer constant" is not the same thing as an object declared as a 
"const int".  123 is an integer constant in C.  After "const int A = 
123;" and "int const B = 123;", neither A nor B are "integer constants".

In all examples of the use of the "const" type qualifier in the C11 
standard, type qualifiers come first, as in "const int".  There is a 
inconsistency as to whether "const volatile int i" or "volatile const 
int i" is the preferred ordering - both are used.  But type qualifiers 
are always given before the type in the standard.

[toc] | [prev] | [next] | [standalone]


#89229

FromIke Naar <ike@iceland.freeshell.org>
Date2016-06-15 22:41 +0000
Message-ID<slrn3vfsnm3md4.i2o.ike@iceland.freeshell.org>
In reply to#89217
On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
> On 15/06/16 23:23, Ike Naar wrote:
>> On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
>>> I think it is far nicer to put type qualifiers such as "const" or
>>> "volatile" at the start of the declaration - "const int", not "int
>>> const".  But that is personal opinion, and I'm not sure I can give a
>>> better justification than "I think it is nicer or clearer".  If others
>>> have better reasons for picking one way or the other, I'd be interested
>>> to hear.
>>
>> The terminology used in the C standard documents is "integer constant",
>> not "constant integer".
>>
>
> An "integer constant" is not the same thing as an object declared as a 
> "const int".  123 is an integer constant in C.  After "const int A = 
> 123;" and "int const B = 123;", neither A nor B are "integer constants".
>
> In all examples of the use of the "const" type qualifier in the C11 
> standard, type qualifiers come first, as in "const int".  There is a 
> inconsistency as to whether "const volatile int i" or "volatile const 
> int i" is the preferred ordering - both are used.  But type qualifiers 
> are always given before the type in the standard.

Imagine you want to declare pi as a nonmodifyable pointer-to-int:

  int * const pi;

The 'const' follows (i.e. appears after) the type (int *).
You cannot put the  'const' before the type, because

  const int * pi;

has a different meaning, namely, pi would be a modifyable pointer to an
'int const' or 'const int'.

Likewise, imagine you want to declare ppi as a nonmodifyable
pointer-to-pointer-to-int:

  int * * const pi;

Again, the 'const' appears after the type (int * *), and putting the 'const'
before the type (int * *) would give the declaration a different meaning.
In general, you can say that, as a rule, the 'const' appears after the type.
This holds in more complex examples as well:

  int * const * int const x;

means that x is a nonmodifyble pointer-to-nonmodifyable-pointer-to-int.

Only at the top level you have the freedom to put the 'const' before or
after the type:

  const int i;

or

  int const i;

So, the top level forms an exception to the rule that the 'const' comes
after the type.
I think that following the rule (always putting 'const' after the type)
makes more sense than following the exception (putting the 'const' after
the type except at the top level).

[toc] | [prev] | [next] | [standalone]


#89230

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-06-15 18:54 -0400
Message-ID<e876e4b6-03b8-8671-6931-120d0d66b109@verizon.net>
In reply to#89229
On 06/15/2016 06:41 PM, Ike Naar wrote:
...
>   int * const * int const x;

The syntax for pointer declarations doesn't allow anything other than
type qualifiers between the '*' and the part that 6.7.6.1p1 calls "D".
In this context, "D" refers to "x", and the second 'int' is therefore a
syntax error.

[toc] | [prev] | [next] | [standalone]


#89252

FromIke Naar <ike@iceland.freeshell.org>
Date2016-06-16 05:41 +0000
Message-ID<slrn3vfsnm4evd.2ic.ike@iceland.freeshell.org>
In reply to#89230
On 2016-06-15, James R. Kuyper <jameskuyper@verizon.net> wrote:
> On 06/15/2016 06:41 PM, Ike Naar wrote:
> ...
>>   int * const * int const x;
>
> The syntax for pointer declarations doesn't allow anything other than
> type qualifiers between the '*' and the part that 6.7.6.1p1 calls "D".
> In this context, "D" refers to "x", and the second 'int' is therefore a
> syntax error.

You're right. It was a typo, the second 'int' shouldn't be there.

[toc] | [prev] | [next] | [standalone]


#89254

FromDavid Brown <david.brown@hesbynett.no>
Date2016-06-16 09:12 +0200
Message-ID<njtjgg$mik$1@dont-email.me>
In reply to#89229
On 16/06/16 00:41, Ike Naar wrote:
> On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
>> On 15/06/16 23:23, Ike Naar wrote:
>>> On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
>>>> I think it is far nicer to put type qualifiers such as "const" or
>>>> "volatile" at the start of the declaration - "const int", not "int
>>>> const".  But that is personal opinion, and I'm not sure I can give a
>>>> better justification than "I think it is nicer or clearer".  If others
>>>> have better reasons for picking one way or the other, I'd be interested
>>>> to hear.
>>>
>>> The terminology used in the C standard documents is "integer constant",
>>> not "constant integer".
>>>
>>
>> An "integer constant" is not the same thing as an object declared as a 
>> "const int".  123 is an integer constant in C.  After "const int A = 
>> 123;" and "int const B = 123;", neither A nor B are "integer constants".
>>
>> In all examples of the use of the "const" type qualifier in the C11 
>> standard, type qualifiers come first, as in "const int".  There is a 
>> inconsistency as to whether "const volatile int i" or "volatile const 
>> int i" is the preferred ordering - both are used.  But type qualifiers 
>> are always given before the type in the standard.
> 
> Imagine you want to declare pi as a nonmodifyable pointer-to-int:
> 
>   int * const pi;
> 
> The 'const' follows (i.e. appears after) the type (int *).
> You cannot put the  'const' before the type, because
> 
>   const int * pi;
> 
> has a different meaning, namely, pi would be a modifyable pointer to an
> 'int const' or 'const int'.
> 
> Likewise, imagine you want to declare ppi as a nonmodifyable
> pointer-to-pointer-to-int:
> 
>   int * * const pi;
> 
> Again, the 'const' appears after the type (int * *), and putting the 'const'
> before the type (int * *) would give the declaration a different meaning.
> In general, you can say that, as a rule, the 'const' appears after the type.
> This holds in more complex examples as well:
> 
>   int * const * int const x;
> 
> means that x is a nonmodifyble pointer-to-nonmodifyable-pointer-to-int.
> 
> Only at the top level you have the freedom to put the 'const' before or
> after the type:
> 
>   const int i;
> 
> or
> 
>   int const i;
> 
> So, the top level forms an exception to the rule that the 'const' comes
> after the type.
> I think that following the rule (always putting 'const' after the type)
> makes more sense than following the exception (putting the 'const' after
> the type except at the top level).
> 

That makes sense, and is a reasonable justification for preferring "int
const".  (The same goes for Stefan's post.)

On the other hand, I think that since const objects, or pointers to
const objects, outweigh the use of const pointers to objects (at least
in my own code), then the emphasis should be on what works best for the
common case.

[toc] | [prev] | [next] | [standalone]


#89218

FromKeith Thompson <kst-u@mib.org>
Date2016-06-15 14:53 -0700
Message-ID<ln8ty6xgnt.fsf@kst-u.example.com>
In reply to#89210
Ike Naar <ike@iceland.freeshell.org> writes:
> On 2016-06-15, David Brown <david.brown@hesbynett.no> wrote:
>> I think it is far nicer to put type qualifiers such as "const" or
>> "volatile" at the start of the declaration - "const int", not "int
>> const".  But that is personal opinion, and I'm not sure I can give a
>> better justification than "I think it is nicer or clearer".  If others
>> have better reasons for picking one way or the other, I'd be interested
>> to hear.
>
> The terminology used in the C standard documents is "integer constant",
> not "constant integer".

No, an "integer constant" is, for example, 42 or 0xff.  "const" does not
mean constant; it means read-only.

The examples in the C standard typically have "const" and/or "volatile"
at the beginning of the declaration (except in cases where it has to
follow a "*", for example).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web