General Category > Ideas

Syntax of const pointers

(1/2) > >>

bas:
I'm currently working on the Type system of C2 and ran into a syntax issue that
I would like to think about more and get more input about.

I'll start by briefly describing the syntax of (ansi-)C in this regard:

--- Code: ---const int
--- End code ---
means an integer that cannot be changed.

--- Code: ---int*
--- End code ---
a pointer to an integer. So far so good. Now for the tricky part:

--- Code: ---const int*
int const*
--- End code ---
Both are equal and describe a pointer to an integer that cannot be changed. The pointer itself can be changed to point
at something else. Syntax here is already becoming more vague.

--- Code: ---int* const
--- End code ---
Okaaaay So this is a constant pointer to an int. The int can be changed (through the pointer), but the pointer itself
will always point to the same int.

--- Code: ---const int* const
--- End code ---
The final version, both the pointer and the value it points to cannot be changed.

Since C2 tries to improve C, this piece of trickery begs to be upgraded.
I currently see 3 options:
1. Add some parentheses
ansi-C  ->    C2const intconst intconst int*(const int)*int* constconst (int*)const int* constconst (const int*)This does make it a bit more clear, but the syntax suffers also.

2. Require 2 steps for certain types:
ansi-C  ->    C2const intconst intconst int*(const int)*int* consttype IPtr int*;
const IPtrconst int* consttype CIPtr const int*;
const CIPtr

3. <Your idea here>

So please feel free to post.

DerSaidin:

--- Quote from: bas on July 17, 2013, 07:39:26 PM ---Now for the tricky part:

--- Code: ---const int*
int const*
--- End code ---
Both are equal and describe a pointer to an integer that cannot be changed. The pointer itself can be changed to point
at something else. Syntax here is already becoming more vague.

--- End quote ---

I think this is the main problem with const in C, the order of const is varying/inconsistent/different.
It becomes confusing when you usually use 'const int *', and you see 'int const *' and think it means something different. I think it would be an improvement to restrict to specific positioning.

3. Limit positioning
ansi-C  ->    C2const intconst intint constconst intconst int*const int*int const *const int*int* constint* constconst int* constconst int* constconst int * constconst int* constconst int * const *const int* const *const int * const *constconst int* const * const
This positioning is what I usually see and write.
I think this would reduce confusion, and is compatible with C.

However, this is a bit inconsistent:

--- Code: ---const int a = 4;
int * const b = &c;
--- End code ---
The variables a and b are both constant, but in one case the const qualifier is before the type,
in the other case const is before the identifier and after the type.                                                                               

To make it more consistent, you could move the first const, so the const comes after the type it qualifies.
Parentheses shouldn't be needed, think of it as a tightly binding suffix operator.

4. Const qualifier after type
ansi-C  ->    C2const intint constint constint constconst int*int const *int const *int const *int* constint * constconst int* constint const * constconst int * constint const * const
((((int) const) *) const)  // parentheses to clarify ast structureconst int * const *int const * const *
((((int) const) *) const) *)  // parentheses to clarify ast structureconst int * const *constint const * const * const
(((((int) const) *) const) *) const)  // parentheses to clarify ast structure
Now the const qualifier is consistently after the type, and is still compatible with C.
It doesn't have the usual adjective-noun order if you read it left to right, but right to left is ideal:

--- Code: ---int const * const X = &b;
--- End code ---
"X is a constant pointer to a constant int"

It could also be made consistent by always putting the const qualifer before the type.
This takes the * token as the position of the pointer type.

5. Const qualifier before type
ansi-C  ->    C2const intconst intint constconst intconst int*const int *int const *const int *int* constint const *const int* constconst int const *const int * constconst int const *
((const (int)) (const *))  // parentheses to clarify ast structure  :/const int * const *const int const * *const int * const * constconst int const * const *
This is consistent, and it is in the usual adjective-noun order (and the [probably] more common qualifier ordering use in C).
One disadvantage with this is that It breaks compatbility with C. I realize that C compatibility is not a goal, but it does make it less confusing for C developers, who are probably the main audience.

Also, the AST structure isn't nice/clear/elegant to me.



One of the features of type qualifiers is that they can be added to an existing type, you don't need to define a new type for the qualifier. For this reason I don't like Option 2.


If you don't know the language Options 3, 4 and 5 aren't as implicitly obvious as Option 1, but they're still simple and easy to apply once known and save syntactic cluttering of parentheses.


My preference is Option 4 for being consistent, C compatible, and nice to say aloud (by saying tokens right to left).

bas:
I like option 4 as well. The only minor thing is that 'const int' changes to 'int const', so that'll take
a bit getting used to.

It also works well during parsing, since the const qualifier is added to the type (that was parsed left
of it). So we have the type already by then.

To be consistent, the same will apply to other qualifiers (volatile and restrict) as well,
so in case 4, those will be like:
int volatile reg1;
int volatile * const;  // const pointer to volatile int (the most common case in low-level programming).

I'll be away for the next 2 weeks, but i'll keep grinding my head about this.

kyle:
Hmm, I've been programming in C since about 1979 and I never really thought about all the ways const can be stuffed into a type declaration.  I really like #4.

One of the things that Go changed from C was the order of declarations.  At first this seemed a little bit gratuitous.  However, the more Go code I see, the more it makes sense to me.  It is really a fair amount easier to read complicated declarations.

The Go people also did this to simplify the compiler. 

Thanks for writing all these tables up.  This is really useful!

Best,
Kyle

lerno:
Upvote for implementing 4.

Navigation

[0] Message Index

[#] Next page

Go to full version