Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #89090 > unrolled thread
| Started by | BartC <bc@freeuk.com> |
|---|---|
| First post | 2016-06-14 20:53 +0100 |
| Last post | 2016-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.
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
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-06-14 20:53 +0100 |
| Subject | Re: 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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2016-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2016-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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