* Ada Smileys in C++ lib Conversion @ 2010-08-13 14:20 Warren 2010-08-13 15:06 ` Yannick Duchêne (Hibou57) 2010-08-13 16:53 ` Anh Vo 0 siblings, 2 replies; 25+ messages in thread From: Warren @ 2010-08-13 14:20 UTC (permalink / raw) This week I've been busy porting last year's C++ version of my midi library over to Ada (now that I'm using AVR-Ada). As part of that effort, the Ada compiler has discovered a few errors that were lurking still in the C++ Arduino code. In C++ I had defined: /* * MC_CTL_CHG Control values : */ #define MC_CTL_ALLS_OFF 0x78 // All sounds off (120) #define MC_CTL_RESET_C 0x79 // Reset controller #define MC_CTL_LOCAL_C 0x80 // Local on/off #define MC_CTL_ALLN_OFF 0x81 // All notes off #define MC_CTL_OMNI_OFF 0x82 // Omni off request #define MC_CTL_OMNI_ON 0x83 // Omni on request #define MC_CTL_MONO_ON 0x84 // Mono on == POLY OFF #define MC_CTL_MONO_OFF 0x85 // Mono off == POLY ON But in Ada, when I declared: type Control_Type is new Unsigned_8 range 0..127; and then coded: case Control is when MC_CTL_ALLS_OFF => -- ok ... when MC_CTL_LOCAL_C => -- oops ... it immediately identified the value MC_CTL_LOCAL_C (and others) as not fitting into the Control_Type's valid range. In C++ a glaring error had gone unnoticed: #define MC_CTL_ALLS_OFF 0x78 // All sounds off (120) #define MC_CTL_RESET_C 0x79 // Reset controller #define MC_CTL_LOCAL_C 0x7A <==== not 0x80 #define MC_CTL_ALLN_OFF 0x7B <==== not 0x81.. Non commands in midi should not have had bit 7 set. So as it was coded, those control messages would never have been processed in the C++ lib. I'm always smiling when I convert code from C/C++ to Ada. In code of any significant size, Ada always discovers problems that went unnoticed in C/C++. Warren ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-13 14:20 Ada Smileys in C++ lib Conversion Warren @ 2010-08-13 15:06 ` Yannick Duchêne (Hibou57) 2010-08-13 16:53 ` Anh Vo 1 sibling, 0 replies; 25+ messages in thread From: Yannick Duchêne (Hibou57) @ 2010-08-13 15:06 UTC (permalink / raw) Le Fri, 13 Aug 2010 16:20:16 +0200, Warren <ve3wwg@gmail.com> a écrit: > it immediately identified the value MC_CTL_LOCAL_C > (and others) as not fitting into the Control_Type's > valid range. In C++ a glaring error had gone > unnoticed: > [...] > I'm always smiling when I convert code from C/C++ to > Ada. In code of any significant size, Ada always > discovers problems that went unnoticed in C/C++. Makes me think about a recent case where I though “A C/C++ compiler would have never caught it”. This was with AdaDep, a tool from AdaLog (by J.P. Rosen). Since the last revision of Ada, ASIS has also evolved and added a new item in the Asis.Element_Kinds enumeration (this item is An_Expression_Path). Immediately caught by Ada in AdaDep which was not compiling anymore, and the same in another other little application of mine. This indeed help to feel at rest when you see such missing/oversight immediately caught. -- There is even better than a pragma Assert: a SPARK --# check. --# check C and WhoKnowWhat and YouKnowWho; --# assert Ada; -- i.e. forget about previous premises which leads to conclusion -- and start with new conclusion as premise. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-13 14:20 Ada Smileys in C++ lib Conversion Warren 2010-08-13 15:06 ` Yannick Duchêne (Hibou57) @ 2010-08-13 16:53 ` Anh Vo 2010-08-14 1:36 ` Warren 1 sibling, 1 reply; 25+ messages in thread From: Anh Vo @ 2010-08-13 16:53 UTC (permalink / raw) On Aug 13, 7:20 am, Warren <ve3...@gmail.com> wrote: > it immediately identified the value MC_CTL_LOCAL_C > (and others) as not fitting into the Control_Type's > valid range. In C++ a glaring error had gone > unnoticed: [...] > I'm always smiling when I convert code from C/C++ to > Ada. In code of any significant size, Ada always > discovers problems that went unnoticed in C/C++. > I am smiling, too, since I am not surprised at all. When someone asks me what difference between computer languages especially between Ada and C/C++, I tell him Ada has 75% check at compile time and 25% and runtime while C/C++ in reverse. Anh Vo ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-13 16:53 ` Anh Vo @ 2010-08-14 1:36 ` Warren 2010-08-14 9:52 ` Georg Bauhaus 2010-08-14 10:57 ` Brian Drummond 0 siblings, 2 replies; 25+ messages in thread From: Warren @ 2010-08-14 1:36 UTC (permalink / raw) On Aug 13, 12:53 pm, Anh Vo <anhvofrc...@gmail.com> wrote: > On Aug 13, 7:20 am, Warren <ve3...@gmail.com> wrote: > > > > > it immediately identified the value MC_CTL_LOCAL_C > > (and others) as not fitting into the Control_Type's > > valid range. In C++ a glaring error had gone > > unnoticed: > [...] > > I'm always smiling when I convert code from C/C++ to > > Ada. In code of any significant size, Ada always > > discovers problems that went unnoticed in C/C++. > > I am smiling, too, since I am not surprised at all. When someone asks > me what difference between computer languages especially between Ada > and C/C++, I tell him Ada has 75% check at compile time and 25% and > runtime while C/C++ in reverse. > > Anh Vo Heh heh. This is one of those things that C/C++ cannot guard against at all. Unless the value(s) were to exceed the underlying type's storage capability, the compiler is helpless to identify it. There is simply no concept of a "range" of valid values in that language. About the only thing you could do (in C/C++) is to code a macro check on the constants, but I don't think I've ever seen it done in practice. Only as a argument value assertion check in strategic places. But if you leave it up to programmers coding assertions, then you know they won't exist everywhere they're needed. Warren ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 1:36 ` Warren @ 2010-08-14 9:52 ` Georg Bauhaus 2010-08-14 10:57 ` Brian Drummond 1 sibling, 0 replies; 25+ messages in thread From: Georg Bauhaus @ 2010-08-14 9:52 UTC (permalink / raw) On 8/14/10 3:36 AM, Warren wrote: > Heh heh. This is one of those things that C/C++ cannot > guard against at all. Unless the value(s) were to exceed > the underlying type's storage capability, the compiler > is helpless to identify it. There is simply no concept of > a "range" of valid values in that language. You might want to look at Maciej's demo of range checked types in C++, though. Since C++ programmers and language makers are fine with things defined in libraries, not language, they can point to programmers who just have to ... > But if you leave it up to programmers coding assertions, > then you know they won't exist everywhere they're needed. Bad programmers cannot be held responsible for a perfectly applicable language design when they don't know how to use the language properly;-) Georg ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 1:36 ` Warren 2010-08-14 9:52 ` Georg Bauhaus @ 2010-08-14 10:57 ` Brian Drummond 2010-08-14 20:34 ` Maciej Sobczak 2010-08-16 14:54 ` Warren 1 sibling, 2 replies; 25+ messages in thread From: Brian Drummond @ 2010-08-14 10:57 UTC (permalink / raw) On Fri, 13 Aug 2010 18:36:38 -0700 (PDT), Warren <ve3wwg@gmail.com> wrote: >On Aug 13, 12:53�pm, Anh Vo <anhvofrc...@gmail.com> wrote: >> On Aug 13, 7:20�am, Warren <ve3...@gmail.com> wrote: #define MC_CTL_LOCAL_C 0x80 // Local on/off #define MC_CTL_ALLN_OFF 0x81 // All notes off >> > it immediately identified the value MC_CTL_LOCAL_C >> > (and others) as not fitting into the Control_Type's >> > valid range. In C++ a glaring error had gone >> > unnoticed: >> I am smiling, too, since I am not surprised at all. >Heh heh. This is one of those things that C/C++ cannot >guard against at all. Unless the value(s) were to exceed >the underlying type's storage capability, the compiler >is helpless to identify it. There is simply no concept of >a "range" of valid values in that language. > >About the only thing you could do (in C/C++) is to code >a macro check on the constants, but I don't think I've >ever seen it done in practice. Only as a argument value >assertion check in strategic places. Heh too. I thought I was being really really smart years ago in C, when I decided to convert all those #defines to integer constants... const int MC_CTL_LOCAL_C = 0x80; and so on. Of course I was declaring integer variables, who's storage class happens to be named "constant". But it certainly puzzled me to be told that I couldn't use a "const" in a constant expression! - Brian ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 10:57 ` Brian Drummond @ 2010-08-14 20:34 ` Maciej Sobczak 2010-08-14 21:01 ` Dmitry A. Kazakov 2010-08-15 1:16 ` Brian Drummond 2010-08-16 14:54 ` Warren 1 sibling, 2 replies; 25+ messages in thread From: Maciej Sobczak @ 2010-08-14 20:34 UTC (permalink / raw) On 14 Sie, 12:57, Brian Drummond <brian_drumm...@btconnect.com> wrote: > I thought I was being really really smart years ago in C, when I decided to > convert all those #defines to integer constants... > > const int MC_CTL_LOCAL_C = 0x80; > and so on. Yes, this is a good practice. It is better to avoid using preprocessor for anything other than so called include guards. > Of course I was declaring integer variables, who's storage class happens to be > named "constant". No, there is no such storage class. If these objects were globals (which was most likely the case), then their storage class is static. Const means that the given name cannot be used to modify the referred object and has nothing to do with the storage class (it might influence the linkage, though). > But it certainly puzzled me to be told that I couldn't use a "const" in a > constant expression! And what would that mean, anyway? How would you want to use it and what would you like to achieve with it? -- Maciej Sobczak * http://www.inspirel.com YAMI4 - Messaging Solution for Distributed Systems http://www.inspirel.com/yami4 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 20:34 ` Maciej Sobczak @ 2010-08-14 21:01 ` Dmitry A. Kazakov 2010-08-15 1:16 ` Brian Drummond 1 sibling, 0 replies; 25+ messages in thread From: Dmitry A. Kazakov @ 2010-08-14 21:01 UTC (permalink / raw) On Sat, 14 Aug 2010 13:34:54 -0700 (PDT), Maciej Sobczak wrote: > On 14 Sie, 12:57, Brian Drummond <brian_drumm...@btconnect.com> wrote: >> But it certainly puzzled me to be told that I couldn't use a "const" in a >> constant expression! > > And what would that mean, anyway? How would you want to use it and > what would you like to achieve with it? What? Since you can convert (const char *) to (char *), it seems perfectly in C++ style that you also could convert something that is not static to static! const int I = (const) getc(); // Do what I tell you! (Don't take this seriously. (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 20:34 ` Maciej Sobczak 2010-08-14 21:01 ` Dmitry A. Kazakov @ 2010-08-15 1:16 ` Brian Drummond 2010-08-15 10:04 ` Maciej Sobczak 2010-08-24 10:12 ` David Thompson 1 sibling, 2 replies; 25+ messages in thread From: Brian Drummond @ 2010-08-15 1:16 UTC (permalink / raw) On Sat, 14 Aug 2010 13:34:54 -0700 (PDT), Maciej Sobczak <see.my.homepage@gmail.com> wrote: >On 14 Sie, 12:57, Brian Drummond <brian_drumm...@btconnect.com> wrote: > >> I thought I was being really really smart years ago in C, when I decided to >> convert all those #defines to integer constants... >> >> const int MC_CTL_LOCAL_C �= 0x80; >> and so on. > >Yes, this is a good practice. It is better to avoid using preprocessor >for anything other than so called include guards. Except when the result doesn't work! >> Of course I was declaring integer variables, who's storage class happens to be >> named "constant". >No, there is no such storage class. If these objects were globals >(which was most likely the case), then their storage class is static. OK you're right, it's a type qualifier not a storage class. >Const means that the given name cannot be used to modify the referred >object and has nothing to do with the storage class (it might >influence the linkage, though). However, it does NOT mean the referred object cannot be modifed. Nor does it mean that you can use the object just anywhere you'd expect to use a constant. >> But it certainly puzzled me to be told that I couldn't use a "const" in a >> constant expression! > >And what would that mean, anyway? How would you want to use it and >what would you like to achieve with it? In this instance I wanted to declare an array whose size was the constant expression in question. - Brian ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-15 1:16 ` Brian Drummond @ 2010-08-15 10:04 ` Maciej Sobczak 2010-08-16 12:08 ` Brian Drummond 2010-08-16 12:30 ` Brian Drummond 2010-08-24 10:12 ` David Thompson 1 sibling, 2 replies; 25+ messages in thread From: Maciej Sobczak @ 2010-08-15 10:04 UTC (permalink / raw) On 15 Sie, 03:16, Brian Drummond <brian_drumm...@btconnect.com> wrote: > >Yes, this is a good practice. It is better to avoid using preprocessor > >for anything other than so called include guards. > > Except when the result doesn't work! If the result of *not* using preprocessor doesn't work, then with preprocessor it would be even worse. Can you give an example where using preprocessor works correctly, whereas using typed constants does not? > >Const means that the given name cannot be used to modify the referred > >object and has nothing to do with the storage class (it might > >influence the linkage, though). > > However, it does NOT mean the referred object cannot be modifed. It cannot be modified via this name. > Nor does it mean that you can use the object just anywhere you'd > expect to use a constant. Example, please. Example that shows that I cannot use const object where constant is expected. (Hint: there are some *very* obscure corner cases with templates, but if you are there already, you are screwed anyway.) > >> But it certainly puzzled me to be told that I couldn't use a "const" in a > >> constant expression! > > >And what would that mean, anyway? How would you want to use it and > >what would you like to achieve with it? > > In this instance I wanted to declare an array whose size was the constant > expression in question. const int size = 7; int array[size]; Is this what you need? No problem with that. -- Maciej Sobczak * http://www.inspirel.com YAMI4 - Messaging Solution for Distributed Systems http://www.inspirel.com/yami4 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-15 10:04 ` Maciej Sobczak @ 2010-08-16 12:08 ` Brian Drummond 2010-08-16 12:13 ` Georg Bauhaus 2010-08-16 12:30 ` Brian Drummond 1 sibling, 1 reply; 25+ messages in thread From: Brian Drummond @ 2010-08-16 12:08 UTC (permalink / raw) On Sun, 15 Aug 2010 03:04:54 -0700 (PDT), Maciej Sobczak <see.my.homepage@gmail.com> wrote: >On 15 Sie, 03:16, Brian Drummond <brian_drumm...@btconnect.com> wrote: > >> >Yes, this is a good practice. It is better to avoid using preprocessor >> >for anything other than so called include guards. >> >> Except when the result doesn't work! > >If the result of *not* using preprocessor doesn't work, then with >preprocessor it would be even worse. >Example, please. Example that shows that I cannot use const object >where constant is expected. > >(Hint: there are some *very* obscure corner cases with templates, but >if you are there already, you are screwed anyway.) >> In this instance I wanted to declare an array whose size was the constant >> expression in question. > >const int size = 7; >int array[size]; error: variably modifed 'array' at file scope - Brian ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 12:08 ` Brian Drummond @ 2010-08-16 12:13 ` Georg Bauhaus 0 siblings, 0 replies; 25+ messages in thread From: Georg Bauhaus @ 2010-08-16 12:13 UTC (permalink / raw) On 16.08.10 14:08, Brian Drummond wrote: >> const int size = 7; >> int array[size]; > > error: variably modifed 'array' at file scope I believe this warning might be issued by a C compiler, but not by a C++ compiler. Georg ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-15 10:04 ` Maciej Sobczak 2010-08-16 12:08 ` Brian Drummond @ 2010-08-16 12:30 ` Brian Drummond 2010-08-16 12:39 ` Maciej Sobczak 1 sibling, 1 reply; 25+ messages in thread From: Brian Drummond @ 2010-08-16 12:30 UTC (permalink / raw) On Sun, 15 Aug 2010 03:04:54 -0700 (PDT), Maciej Sobczak <see.my.homepage@gmail.com> wrote: >On 15 Sie, 03:16, Brian Drummond <brian_drumm...@btconnect.com> wrote: >Example, please. Example that shows that I cannot use const object >where constant is expected. >> In this instance I wanted to declare an array whose size was the constant >> expression in question. > >const int size = 7; >int array[size]; > >Is this what you need? No problem with that. The real case was a bit stranger than previous reply (simplifying to a 1-D array) const int xdim = 7; const int size = xdim; // was a function of all dimensions int array[size]; ... error: initializer element is not constant error: variably modifed 'array' at file scope So a "const" is not constant, says the compiler. - Brian ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 12:30 ` Brian Drummond @ 2010-08-16 12:39 ` Maciej Sobczak 2010-08-16 21:39 ` Brian Drummond 0 siblings, 1 reply; 25+ messages in thread From: Maciej Sobczak @ 2010-08-16 12:39 UTC (permalink / raw) On 16 Sie, 14:30, Brian Drummond <brian_drumm...@btconnect.com> wrote: > The real case was a bit stranger than previous reply (simplifying to a 1-D > array) > > const int xdim = 7; > const int size = xdim; // was a function of all dimensions > int array[size]; > ... > error: initializer element is not constant > error: variably modifed 'array' at file scope > > So a "const" is not constant, says the compiler. The above is guaranteed to work by the C++ standard (nerds see 5.19/1). The problem will be when the initializer for "size" above will indeed be a function call - this would not be a constant expression, even though the object "size" is declared as const. The reason is that constant expression should always evaluate to the same value, whereas function calls are not required (and cannot be verified) to do so. So, there is a difference between a "constant expression" (roughly equivalent to Ada's "static expression") and a "const object". Array bounds require constant expression. -- Maciej Sobczak * http://www.inspirel.com YAMI4 - Messaging Solution for Distributed Systems http://www.inspirel.com/yami4 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 12:39 ` Maciej Sobczak @ 2010-08-16 21:39 ` Brian Drummond 2010-08-16 22:53 ` Robert A Duff 0 siblings, 1 reply; 25+ messages in thread From: Brian Drummond @ 2010-08-16 21:39 UTC (permalink / raw) On Mon, 16 Aug 2010 05:39:34 -0700 (PDT), Maciej Sobczak <see.my.homepage@gmail.com> wrote: >On 16 Sie, 14:30, Brian Drummond <brian_drumm...@btconnect.com> wrote: >> So a "const" is not constant, says the compiler. > >The above is guaranteed to work by the C++ standard (nerds see >5.19/1). And it does work in C++. (It was clear I was talking about C, yes?). >The problem will be when the initializer for "size" above will indeed >be a function call - this would not be a constant expression, even >though the object "size" is declared as const. >The reason is that constant expression should always evaluate to the >same value, whereas function calls are not required (and cannot be >verified) to do so. ... even though the function is only called once to initialise the const - and it is a "pure function" in Ada or VHDL terms - and all its arguments are consts (or even constants!). Does make me wonder what _can_ be verified in C++. >So, there is a difference between a "constant expression" (roughly >equivalent to Ada's "static expression") and a "const object". >Array bounds require constant expression. So we have - even in C++ - a const object that cannot be used where a constant expression is required. Interesting, Thanks. To get back almost on-topic, I am frequently amazed in Ada, after years of bruising by various {}-languages, how often I can program from the BNF, (i.e. "the BNF doesn't stop me doing this, but surely it can't be THAT simple..." and it just works. - Brian ... smiling ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 21:39 ` Brian Drummond @ 2010-08-16 22:53 ` Robert A Duff 0 siblings, 0 replies; 25+ messages in thread From: Robert A Duff @ 2010-08-16 22:53 UTC (permalink / raw) Brian Drummond <brian_drummond@btconnect.com> writes: > On Mon, 16 Aug 2010 05:39:34 -0700 (PDT), Maciej Sobczak > <see.my.homepage@gmail.com> wrote: >>So, there is a difference between a "constant expression" (roughly >>equivalent to Ada's "static expression") and a "const object". >>Array bounds require constant expression. > > So we have - even in C++ - a const object that cannot be used > where a constant expression is required. Seems to me Ada and C++ are the same here. It's the different terminology that's confusing. In Ada, a "constant" object initialized by a user-defined function call cannot be used in a "static" expression. In C++, a "const" object initialized by a user-defined function call cannot be used in a "constant" expression. Same thing, different words. C is different from both C++ and Ada in this area. - Bob ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-15 1:16 ` Brian Drummond 2010-08-15 10:04 ` Maciej Sobczak @ 2010-08-24 10:12 ` David Thompson 2010-08-30 9:51 ` Brian Drummond 1 sibling, 1 reply; 25+ messages in thread From: David Thompson @ 2010-08-24 10:12 UTC (permalink / raw) On Sun, 15 Aug 2010 02:16:15 +0100, Brian Drummond <brian_drummond@btconnect.com> wrote: > On Sat, 14 Aug 2010 13:34:54 -0700 (PDT), Maciej Sobczak > <see.my.homepage@gmail.com> wrote: <snip: C const int> > >> Of course I was declaring integer variables, who's storage class happens to be > >> named "constant". > >No, there is no such storage class. If these objects were globals > >(which was most likely the case), then their storage class is static. > > OK you're right, it's a type qualifier not a storage class. > > >Const means that the given name cannot be used to modify the referred > >object and has nothing to do with the storage class (it might > >influence the linkage, though). > Depends which linkage. 'linkage' is a term of art in the C standard, with external or 'global globals' visible throughout the program vs internal or 'file globals' visible only in one (preprocesed) source file and declared with the misleading keyword 'static'. C++ adds namespaces (~packages) which can hierarchically organize external names. And it makes const objects (~variables) (and references) default to internal linkage vs external in C (except locals have no linkage). (C++ also adds a separate but similar 'language linkage' for interop with C and potentially others.) And as already noted, in C++ but not C a const object of integer or enumeration type initialized by a constant expression is usable as a compile-time constant (where a constant expression is required, including array bound, case label, etc.) If you mean linkage as the normal compiler+linker+run process, yes static duration objects that are const qualified can be put in a separate section (or equivalent depending on platform) that is readonly at runtime e.g. .RODATA instead of .DATA . > However, it does NOT mean the referred object cannot be modifed. > Nor does it mean that you can use the object just anywhere you'd > expect to use a constant. > An object (~variable) _definition_ in C (a declaration that also allocates the storage) with qualifier 'const' means that a store through that name (or other const 'lvalue' ~view) is a 'Constraint Violation' and must be diagnosed, but if you 'cheat' and get a nonconst lvalue, any store to it is 'Undefined Behavior' according to the standard. U.B. is like Ada erroneous -- a program mustn't do it, but an implementation isn't required to diagnose it. In practice usually either the object is actually writable and the write works, or it is allocated to readonly address-space (as above) and the write either traps or is silently ignored. But the compiler is allowed to assume no such erroneous write occurs, and fold the (visible) declared initialization value to any read. And other declarations that _refer_ to the object must be 'compatible' according to specific rules, and const T and nonconst T aren't. Again in practice, this will usually work in the sense of accessing the correct memory location, and writes using that name either will or won't work, but officially this also is U.B. Pointer targets are different. If I declare 'const int * p' I can point p to either a const or nonconst int object, and I can't use _that name_ i.e. *p= (or p[i]= if it's actually in an array) to store to it, but if the actual object is nonconst other pointers/name can legally modify it, including a cast of p to nonconst int *. And similarly for references in C++, which also adds a specific syntax const_cast<T> to do only dequalification (actually both const and volatile, but volatile is probably <<1e-6 of the uses). And yes, as above, in C++ but not C you can use a const int/enum object with constant initializer as a constant expression. > >> But it certainly puzzled me to be told that I couldn't use a "const" in a > >> constant expression! > > > >And what would that mean, anyway? How would you want to use it and > >what would you like to achieve with it? > > In this instance I wanted to declare an array whose size was the constant > expression in question. > Yes. You can get this particular case in C (and C++ if you wish) by declaring a constant in an enum type (which needn't be otherwise used), but (1) it looks confusing (how does this value relate to this enum?) and (2) it's limited to (signed) 'int' in C ('long' in C++); that's _often_ enough for any supported array bound, but not always. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-24 10:12 ` David Thompson @ 2010-08-30 9:51 ` Brian Drummond 0 siblings, 0 replies; 25+ messages in thread From: Brian Drummond @ 2010-08-30 9:51 UTC (permalink / raw) On Tue, 24 Aug 2010 06:12:04 -0400, David Thompson <dave.thompson2@verizon.net> wrote: >On Sun, 15 Aug 2010 02:16:15 +0100, Brian Drummond ><brian_drummond@btconnect.com> wrote: > >> On Sat, 14 Aug 2010 13:34:54 -0700 (PDT), Maciej Sobczak >> <see.my.homepage@gmail.com> wrote: ><snip: C const int> >> >No, there is no such storage class. If these objects were globals >> >(which was most likely the case), then their storage class is static. >> >> OK you're right, it's a type qualifier not a storage class. >> >Const means that the given name cannot be used to modify the referred >> >object and has nothing to do with the storage class (it might >> >influence the linkage, though). >> >Depends which linkage. 'linkage' is a term of art in the C standard, >with external or 'global globals' visible throughout the program vs >internal or 'file globals' visible only in one (preprocesed) source >file and declared with the misleading keyword 'static'. Thank you for a concise summary! - Brian ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-14 10:57 ` Brian Drummond 2010-08-14 20:34 ` Maciej Sobczak @ 2010-08-16 14:54 ` Warren 2010-08-16 20:27 ` Maciej Sobczak 1 sibling, 1 reply; 25+ messages in thread From: Warren @ 2010-08-16 14:54 UTC (permalink / raw) Brian Drummond expounded in news:95tc66hjv3stdk0nhdv9o46e5l2ecdog5j@4ax.com: >>About the only thing you could do (in C/C++) is to code >>a macro check on the constants, but I don't think I've >>ever seen it done in practice. Only as a argument value >>assertion check in strategic places. > > Heh too. > > I thought I was being really really smart years ago in C, when I > decided to convert all those #defines to integer constants... > > const int MC_CTL_LOCAL_C = 0x80; > and so on. .. > - Brian Another approach is to declare them as enums. But this is unhelpful because they are all implemented as int's. Further, the switch statement doesn't tell you about the cases which are missing. Warren ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 14:54 ` Warren @ 2010-08-16 20:27 ` Maciej Sobczak 2010-08-17 12:57 ` Warren 0 siblings, 1 reply; 25+ messages in thread From: Maciej Sobczak @ 2010-08-16 20:27 UTC (permalink / raw) On 16 Sie, 16:54, Warren <ve3...@gmail.com> wrote: > > const int MC_CTL_LOCAL_C = 0x80; > > and so on. > Another approach is to declare them as enums. But this > is unhelpful because they are all implemented as int's. No. Enums are separate types. > Further, the switch statement doesn't tell you about the > cases which are missing. Try g++ -Wswitch. -- Maciej Sobczak * http://www.inspirel.com YAMI4 - Messaging Solution for Distributed Systems http://www.inspirel.com/yami4 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-16 20:27 ` Maciej Sobczak @ 2010-08-17 12:57 ` Warren 2010-08-17 13:37 ` Maciej Sobczak 2010-08-24 10:12 ` David Thompson 0 siblings, 2 replies; 25+ messages in thread From: Warren @ 2010-08-17 12:57 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 705 bytes --] Maciej Sobczak expounded in news:be7c80ac-3fce-4779-8542- 115567f649de@g17g2000yqe.googlegroups.com: > On 16 Sie, 16:54, Warren <ve3...@gmail.com> wrote: > >> > const int MC_CTL_LOCAL_C �= 0x80; >> > and so on. > >> Another approach is to declare them as enums. But this >> is unhelpful because they are all implemented as int's. > > No. Enums are separate types. They are considered different "types" but (in C at least), they're implemented as ints. IOW, you can't mix the enums but you can supply an enum in an int argument. >> Further, the switch statement doesn't tell you about the >> cases which are missing. > > Try g++ -Wswitch. GCC extension. Try it on HP or AIX C compiler. Warren ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-17 12:57 ` Warren @ 2010-08-17 13:37 ` Maciej Sobczak 2010-08-17 15:07 ` Georg Bauhaus 2010-08-18 17:31 ` Warren 2010-08-24 10:12 ` David Thompson 1 sibling, 2 replies; 25+ messages in thread From: Maciej Sobczak @ 2010-08-17 13:37 UTC (permalink / raw) On 17 Sie, 14:57, Warren <ve3...@gmail.com> wrote: > > No. Enums are separate types. > > They are considered different "types" but (in C at least), > they're implemented as ints. IOW, you can't mix the enums > but you can supply an enum in an int argument. This is called "implicit conversion" and has nothing to do with how enums are implemented. I agree, however, that implicit conversions cause problems. > >> Further, the switch statement doesn't tell you about the > >> cases which are missing. > > > Try g++ -Wswitch. > > GCC extension. No, it is not an extension. It is a compiler option. The language standard does not define what options the compiler should support, so it does not make much sense to declare that some option is an extension. All options are features of respective products and products compete by offering different sets of features. For example, GNAT can check some code formatting rules. This is a feature of the compiler, not a language extension. > Try it on HP or AIX C compiler. And your point is? It is true that the language standard does not mandate such coverage check (unlike in Ada), but that does not make such analysis unfeasible or forbidden. Coming back to enums - they can help in such analysis and that's one of the reasons to use them instead of ints. -- Maciej Sobczak * http://www.inspirel.com ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-17 13:37 ` Maciej Sobczak @ 2010-08-17 15:07 ` Georg Bauhaus 2010-08-18 17:31 ` Warren 1 sibling, 0 replies; 25+ messages in thread From: Georg Bauhaus @ 2010-08-17 15:07 UTC (permalink / raw) On 17.08.10 15:37, Maciej Sobczak wrote: > On 17 Sie, 14:57, Warren <ve3...@gmail.com> wrote: >>> Try g++ -Wswitch. >> >> GCC extension. > > No, it is not an extension. It is a compiler option. > The language standard does not define what options the compiler should > support, so it does not make much sense to declare that some option is > an extension. All options are features of respective products and > products compete by offering different sets of features. Effectively, with this switch making GCC attempt case coverage, it seems a feature that while not available in C++, is, apparently, still desirable. Here is an observation, then, focusing on programmers and vendors, admittedly somewhat psychological: A compiler switch is a technique used in keeping face, establishing a cover-up. For C++ or for Ada, if the switch isn't turning on support for experimental language, it can be a hint at the presence of a deficiency. A "compiler switch" leaves the language of choice as "perfect" as it is; it leaves room for more or less reasonable hands-waving arguments. "The original C switch is great! Because ...". Duff's device comes to mind. "Not forbidden to check", "not unfeasable to support in a compiler", etc., fall in this category (for any language lacking features); I *want* fall-through! In real life, we see tools like lint and coding standards being added on top of the compiler. The purpose is: to pretend we keep using the old language, which is thus kept perfect, even when they rule out parts of the language or, well, extend it with compiler supplied interpretation. If we do not add rhetoric around the "difference between switch-language and LRM-language", we'll have to get real, throw out old junk and adapt---admit that we might foolishly have defended a stupid thing. There is a solution, see below. Unfortunately, one might say, Ada isn't dropping stuff either. As long as there is a handful of paying customers, I think, who allegedly want all new compilers for all old software... Not a tool capable of rewriting the old to the new. Fortunately, there is a backdoor that helps keeping face while dropping stuff from the Ada language, at least. The SPARK approach exemplifies. I still hope something similar is recognized in the C world. The solution is in the hands of those who pay compiler makers: Suppose industry customers decide on a set of requests: 1) Add good language features to the language where missing. 2) Remove bad language features where they create more trouble than anything else. 3) Force vendors to write good source code transformers, from old language to new language. After all, source code transformation is their business! Verifiable source code transformation is a hot subject, so potentially, there is money in it. Georg ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-17 13:37 ` Maciej Sobczak 2010-08-17 15:07 ` Georg Bauhaus @ 2010-08-18 17:31 ` Warren 1 sibling, 0 replies; 25+ messages in thread From: Warren @ 2010-08-18 17:31 UTC (permalink / raw) Maciej Sobczak expounded in news:1b64e5c2-f3d5-41e9-99cb-70e92c074d33 @q22g2000yqm.googlegroups.com: >> >> Further, the switch statement doesn't tell you about the >> >> cases which are missing. >> >> > Try g++ -Wswitch. >> >> GCC extension. > > No, it is not an extension. It is a compiler option. > The language standard does not define what options the compiler should > support, so it does not make much sense to declare that some option is > an extension. All options are features of respective products and > products compete by offering different sets of features. ... >> Try it on HP or AIX C compiler. > > And your point is? > It is true that the language standard does not mandate such coverage > check (unlike in Ada), but that does not make such analysis unfeasible > or forbidden. Now you understand my point, exactly. Warren ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Ada Smileys in C++ lib Conversion 2010-08-17 12:57 ` Warren 2010-08-17 13:37 ` Maciej Sobczak @ 2010-08-24 10:12 ` David Thompson 1 sibling, 0 replies; 25+ messages in thread From: David Thompson @ 2010-08-24 10:12 UTC (permalink / raw) On Tue, 17 Aug 2010 12:57:11 +0000 (UTC), Warren <ve3wwg@gmail.com> wrote: > Maciej Sobczak expounded in news:be7c80ac-3fce-4779-8542- > 115567f649de@g17g2000yqe.googlegroups.com: > > > On 16 Sie, 16:54, Warren <ve3...@gmail.com> wrote: > > > >> > const int MC_CTL_LOCAL_C �= 0x80; > >> > and so on. > > > >> Another approach is to declare them as enums. But this > >> is unhelpful because they are all implemented as int's. > > > > No. Enums are separate types. > > They are considered different "types" but (in C at least), > they're implemented as ints. IOW, you can't mix the enums > but you can supply an enum in an int argument. > Yes but no but yes. In C all enum _constants_ are exactly type '(signed) int' (and within that specific type's range) and an enum _type_ is represented as _some_ supported integer type (like int or short) sufficient to cover the range of constants declared. Most compilers just use 'int' for all enum types, since it is always sufficient, but this isn't required; at least on some targets GCC has -fshort-enums and attribute((packed)). An enum value in most expressions has applied the 'default promotions' which convert it to an integer type (almost always signed int), and a (reasonable) integer value can be assigned or passed by value to any enum. But the types are not formally 'compatible' and e.g. pointer to enum foo is not implicitly convertible to or from pointer to int. C++ makes some changes. First, enum constants can be 'long' and (thus) types up to that, although on some machines that's not actually wider than 'int'. Second, enums convert _to_ integer but not the reverse and not one enum to another, and constants are of enum type not int (or long). Thus e.g. void bar(int x) and void bar(enum foo x) are distinguishable for overloading. > >> Further, the switch statement doesn't tell you about the > >> cases which are missing. > > > > Try g++ -Wswitch. > or slightly stricter -Wswitch-enum . and gcc also. (Or more exactly GCC for both C++ and C, because gcc and g++ are actually drivers that can compile either -- and other supported languages like Ada too; the main difference is which language(s) they can *link*, and at link time compiler-warning settings are no longer applicable.) > GCC extension. Try it on HP or AIX C compiler. > Indeed. ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2010-08-30 9:51 UTC | newest] Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-08-13 14:20 Ada Smileys in C++ lib Conversion Warren 2010-08-13 15:06 ` Yannick Duchêne (Hibou57) 2010-08-13 16:53 ` Anh Vo 2010-08-14 1:36 ` Warren 2010-08-14 9:52 ` Georg Bauhaus 2010-08-14 10:57 ` Brian Drummond 2010-08-14 20:34 ` Maciej Sobczak 2010-08-14 21:01 ` Dmitry A. Kazakov 2010-08-15 1:16 ` Brian Drummond 2010-08-15 10:04 ` Maciej Sobczak 2010-08-16 12:08 ` Brian Drummond 2010-08-16 12:13 ` Georg Bauhaus 2010-08-16 12:30 ` Brian Drummond 2010-08-16 12:39 ` Maciej Sobczak 2010-08-16 21:39 ` Brian Drummond 2010-08-16 22:53 ` Robert A Duff 2010-08-24 10:12 ` David Thompson 2010-08-30 9:51 ` Brian Drummond 2010-08-16 14:54 ` Warren 2010-08-16 20:27 ` Maciej Sobczak 2010-08-17 12:57 ` Warren 2010-08-17 13:37 ` Maciej Sobczak 2010-08-17 15:07 ` Georg Bauhaus 2010-08-18 17:31 ` Warren 2010-08-24 10:12 ` David Thompson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox