do you const OR const do you

category: general [glöplog]
I started reading this book "C++ templates The Complete Guide" (very well written) and right at the start the authors explain why they choose this form

"int const* fool" instead of "const int* fool"

I've always used "const int*", never knowing the other was equivalent.

What do you use?

added on the 2007-12-10 00:34:15 by duffman duffman
the one that compiles.
actually since getting into oop i stopped using const's altogether
added on the 2007-12-10 01:01:33 by psenough psenough
I go with "const int* fool" because it is visually similar to how you do "extern int* fool" and "static int* fool".

I know it is inaccurate, but it is very rare to have an "int * const fool" or an "int const * const fool" and therefore the "const int * fool" works good enough for everyday purposes. I will probably switch to the proper way sometime in the future, though.
added on the 2007-12-10 01:16:35 by Kalms Kalms
"const int*" for me too. didn't know the other one worked...
completely useless discussion (arguing that one is better than the other).

if you know how cv-qualification works, you can read it both ways, if you don't, you're prone to misunderstand it anyway.
added on the 2007-12-10 01:30:44 by ryg ryg
const int *
added on the 2007-12-10 01:31:06 by kusma kusma
Of course most of us use "const int*".

And yes it's an inconsistent usage because const should apply to whatever is on its immediate left.

But hey, the C++ standard made an additional syntax just for us, so we can use this IMHO better readable syntax... So we SHOULD use it ;-)
added on the 2007-12-10 01:45:18 by RufUsul RufUsul
actually since getting into oop i stopped using const's altogether

added on the 2007-12-10 05:03:15 by kb_ kb_
Quite some time ago I switched to "int const*" and its various friends for the very same reason the authors explain in this book.

1. It allows for "Type* const" in formal parameter lists, something that is not possible with the conventional syntax.
2. It works consitently when used in generic functions/classes, which the old syntax doesn't do either.
there's no "new" or "old" syntax here (like with c function declarations), it's all the same syntax. if you don't know what the const applies to, that's entirely your fault.
added on the 2007-12-10 08:13:39 by ryg ryg
int const * const is probably too low level for c++ anyway. Try using a handle class.
@ryg: I fully agree with you, but my point is not about knowing what it applies to.

As a simple example (that suffices to make my point, although it does not convey the whole scope of the problem) let's say you have a template function defined like this:

Code: template<typename ValueType> ValueType bla(const ValueType value) { // ... return value; }

When substituting "int" as the template parameter the outcome is as expected. When substituting "char*" it is not. The post-const syntax avoids these situations.
DoctorRockit: I'm not sure what you mean that you expect here and how that fails for your c-string version...
added on the 2007-12-10 09:38:06 by kusma kusma
what nitpickery.
added on the 2007-12-10 09:42:22 by skrebbel skrebbel
oh, right. const char * cannot be promoted to char *. Well, this looks to me like a design-issue with your bla()-template, but you are of course free to solve it however you wish. I just don't see how you expect any generic template to work for c-strings, especially not when you do your returns like that. Moving the constness to the pointed-at data is IMO just a cheap hack in such cases. I'd very much like to see a more real-world example of your problem.
added on the 2007-12-10 10:02:25 by kusma kusma
Kusma: You're right, my bad. Apologies to you ryg.

Still in the generic substitution case the post-const syntax expresses the intended meaning more naturally, IMO.
Oh well, with a bit of fiddling I managed to produce an, admittedly rather pathologic, case where the substitution fails, when using the prefix syntax:

Code: #define DEFINE_STOOPID_OVERLOAD(type) \ type stoopid(const type test) { return test; } DEFINE_STOOPID_OVERLOAD(int); DEFINE_STOOPID_OVERLOAD(char*);

I have not succeeded in making the prefix version compile as expected, but then again I don't know much about the preprocessor.

A situation where I could imagine something similar to be used in practice is automatically generating a set of overloads of a generic function to (approximately) solve the forwarding problem.
But then again the problem can be easily avoided by introducing typedefs for the generic type that are then used in the function defined in the macro.
yeah well, but in the end you still have to know what happens or risk getting burned. it's easier once you start thinking in terms of how types are internally represented (for me anyway).

but ultimately, the main problem is just that c declaration syntax is notoriously difficult to parse (both for humans and compilers; getting c declarator semantics right is pretty tough), and c++ is even worse.

to give a nice little example (this is C, not even C++):
Code:int*(*const*T[])(int*,struct T{void*const y;}*volatile*const volatile[]);

(intentionally without unnecessary whitespace, you get to see what the compiler sees :). a beer to the first one to figure out what is being declared and which type it has (description in english, not as c code, of course :).
added on the 2007-12-10 10:36:31 by ryg ryg
doctorrockit: very bad example, because the preprocessor doesn't obey syntactic or semantic rules. templates OTOH perform actual type substitution, and your problem goes away.
added on the 2007-12-10 10:47:27 by ryg ryg
Yeah, sure, that's why I named the function "stoopid" ;).

Anyway in TMP the preprocessor is often used for compile-time code-generation purposes. But as I said there are easy workarounds (create a typedef and let the template engine perform the type substitution) for this problem in case someone insists on using the prefix syntax even in those cases.
... and on the sixth day God created the woman and loosely-typed languages, god bless them!
added on the 2007-12-10 11:00:37 by Zest Zest
Anyway the const is only for the programmers.
The compilers not use const for optimize the program.
It's only too preserve the error of programmers and the compilers "agress you" if you attempt to change the variable.
So you can't change the variable and you set "const" just for avoid to change the variable :
it's a protection.
( i hope that you understand this text )
I like consts...

>Anyway the const is only for the programmers.
>The compilers not use const for optimize the program.

I *guess* it does in some cases, if you define some vars as const, the compiler should not translate it as variable, and just read the TOC, things like that.
added on the 2007-12-10 16:38:03 by krabob krabob
If you don't care to use proper const declaration then why are you using such a dangerous language in the first place? Obviously if you cannot understand/bother to use const where you are supposed to you shouldn't touch such dangerous languages.
added on the 2007-12-10 16:38:58 by Hatikvah Hatikvah
actually since getting into oop i stopped using const's altogether

actually i stopped using c++ altogether... (and i'm much happier since that happened!)
added on the 2007-12-10 19:07:53 by blala blala