Jump to page: 1 2 3
Thread overview
Clarifying 'const' terminology
Jul 08, 2006
Derek Parnell
Jul 08, 2006
kris
Read-only array reference (was: Re: Clarifying 'const' terminology)
Jul 08, 2006
Hasan Aljudy
Re: Read-only array reference
Jul 08, 2006
kris
Jul 08, 2006
Sean Kelly
Jul 08, 2006
Hasan Aljudy
Jul 08, 2006
BCS
Re: Read-only array reference
Jul 08, 2006
Bruno Medeiros
Jul 08, 2006
Hasan Aljudy
Jul 09, 2006
Bruno Medeiros
Jul 09, 2006
Hasan Aljudy
Jul 09, 2006
BCS
Jul 08, 2006
Bruno Medeiros
Jul 08, 2006
Kirk McDonald
Jul 08, 2006
Derek Parnell
Jul 09, 2006
Bruno Medeiros
Jul 09, 2006
Hasan Aljudy
Jul 10, 2006
BCS
Jul 08, 2006
Deewiant
Jul 08, 2006
Bruno Medeiros
Jul 08, 2006
Sean Kelly
Jul 08, 2006
Derek Parnell
Jul 09, 2006
Sean Kelly
Jul 09, 2006
Dave
Jul 09, 2006
Bruno Medeiros
Jul 08, 2006
Derek Parnell
July 08, 2006
I'm not from a C++/C#/Java background, so please excuse my lack of understanding about the meaning that is being applied to the term 'const' in these recent discussions.

To me, there seems to be two things being talked about.

(a) Data, which once initialized, is not to be modified for the run-time life of the application.

(b) Data, which once passed to some function, is not to be modified for the run-time life of that function.

Walter's proposed refinement of the 'in' keyword does nothing for type (a), and only limited support for type (b), in that it protects data from the called function but not from functions that that subsequently calls. It is only protection for one level deep. And the only data protected is class objects and not other reference types.

Is there any other types (or subtypes) of 'const' meanings being discussed or considered?

For example, are we distinguishing between compile-time protection and run-time protection?

My requirements for 'const' are almost covered by Walter's new proposal. I'm a quite concerned that if I tell Foo() that it can't change something, that Foo() can still tell Bar() to disregard my request and tell Bar() that it's okay to change it anyway.

I think that apart from array references, type (a) const can be acheived through using private members and public properties. I'm not sure how we can fully implement (a) with current D semantics.

-- 
Derek Parnell
Melbourne, Australia
July 08, 2006
Good idea ~ I'll have a go:

Derek Parnell wrote:
> I'm not from a C++/C#/Java background, so please excuse my lack of  understanding about the meaning that is being applied to the term 'const'  in these recent discussions.
> 
> To me, there seems to be two things being talked about.
> 
> (a) Data, which once initialized, is not to be modified for the run-time  life of the application.


There are the traditional 'constant' read-only data types, assigned at the point of declaration (e.g. char[]s = "foo";). It used to be that these were located into a distinct area of memory from read/write program variables and so on. This was done (partly) so that the read-only aspect could be trapped at runtime by the executing device.

If you try to modify a D string constant on linux, you'll get a runtime error (Win32 D executables let you happily modify such things), so linux is applying read-only attributes to the segment where this constant data lives. However, the distinction is mostly limited to micro-controllers and other devices with limited RAM, but plenty of ROM -- such readonly constants are traditionally stored in ROM.

There's a variation on this called "final", where the constant-value is actually determined at runtime.  That is, you get one opportunity to assign a value to a final data type (such as a string) and that's it. Such a compiler will attach compile-time errors to additional assignments.


> (b) Data, which once passed to some function, is not to be modified for  the run-time life of that function.


This is the realm of where the discussion has been, vis-a-vis mutable and/or immutable attributes. Tis' a shame 'const' is such an overloaded term


> Walter's proposed refinement of the 'in' keyword does nothing for type  (a), and only limited support for type (b), in that it protects data from  the called function but not from functions that that subsequently calls.  It is only protection for one level deep. And the only data protected is  class objects and not other reference types.
> 
> Is there any other types (or subtypes) of 'const' meanings being discussed  or considered?

Other than retaining the immutable attribute throughout a given call chain, the other primary subtype (I suppose) is the return value of a function or method.


> For example, are we distinguishing between compile-time protection and  run-time protection?


For the mutable/immutable aspect, I believe we're talking purely about the compile time aspect. To sum up the whole discussion, it's really about enhancing the contractual obligation between a caller and callee. For example:

As it stands, a callee says "I accept a string as an argument" and the compiler traps those cases, at compile time, where a caller does not provide a string: generates a compile-time error. The mutable attribute enhances this so the callee can say "I need a mutable string, because I will modify it", or "I'm happy with just an immutable string since I use it for read-only purposes".

A caller is then obligated to fulfill the (tighter) contract, in a manner similar to how it is currently obliged to provide just a string.

The benefits of doing so are numerous, and would probably dilute the value of establishing terminology; so we can probably leave it at that for now?


> My requirements for 'const' are almost covered by Walter's new proposal.  I'm a quite concerned that if I tell Foo() that it can't change something,  that Foo() can still tell Bar() to disregard my request and tell Bar()  that it's okay to change it anyway.


Yes, that is a notable weakness. Using an aggregate (struct or class) instead would give you the /propogation/ aspect required. This is in contrast to Walter's proposal, but requires the use of aggregates rather than, say, an array. BTW: this whole discussion is basically about array types, since others can happily be passed by value anyway.

The one problem with using aggregates in this manner is related to return values. For example, you can make a String struct or class and control what each method does to the encapsulated content. At some point, though, the content will likely need exposing. Perhaps via a toString() method or via some other means. Simply duplicating the content at this point is a contentious issue, so some means of tagging the return value as 'immutable', and having that usage enforced, would seem to be necessary.


> I think that apart from array references, type (a) const can be acheived  through using private members and public properties. I'm not sure how we  can fully implement (a) with current D semantics.


Did you mean "... fully implement (b) with current D semantics" instead?

As I understand things, it is array references that are at stake here. I don't think anything else is?
July 08, 2006

kris wrote:
> Good idea ~ I'll have a go:
> 
> Derek Parnell wrote:
> 
>> I'm not from a C++/C#/Java background, so please excuse my lack of  understanding about the meaning that is being applied to the term 'const'  in these recent discussions.

I am from a C++/Java background, yet I still don't fully understand const!
The only thing I understand is that Java doesn't need it because it's higher-level than D, doesn't allow pointer manipulation, and has builtin immutable String class.

I still don't understand why D needs it, or why do some people think so.

> <snip>
>> My requirements for 'const' are almost covered by Walter's new proposal.  I'm a quite concerned that if I tell Foo() that it can't change something,  that Foo() can still tell Bar() to disregard my request and tell Bar()  that it's okay to change it anyway.
> 
> 
> 
> Yes, that is a notable weakness. Using an aggregate (struct or class) instead would give you the /propogation/ aspect required. This is in contrast to Walter's proposal, but requires the use of aggregates rather than, say, an array. BTW: this whole discussion is basically about array types, since others can happily be passed by value anyway.


Then how about introducing a new type: read-only array reference.
(The idea is inspired by Java's immutable string class)

It would be a distinct type, but built into the language core.
It has a different declaration syntax from regular arrays.
It cannot be casted to anything at all, absolutly no pointer manipulation is allowed either.
The content of the array cannot be modified (further explanation below).
The reference itself *can* be modified to refer to another array, but it would still be a read-only reference.
Any type of regular array reference (dynamic/static/associative) can be converted to a read-only array reference.

For example, the syntax could be:
int[$] x; //declare x as a readonly reference to an array of "int"s.

using the $ might not be the best thing, but please bare with me .. that's not the main point.

From now on, I'm gonna assume there's a nice syntax that's consistent with the rest of the D language.

To ensure that the content of the array cannot be modified, some measures must be taken regarding what happens when you read an element from the array.

Let's agree first on some terminology:
Contained Type: if <code> T[$] x; </code> declares a read-only array reference to an array of T's, then T is the contained type.

Now, in theory, the contained type can either be
- a native type (int, float, byte ... enums .. etc)
- a struct
- a class (reference)
- an array or a pointer.

When an element is read from the array, what should we do?
- if the contained type is a native type or an enum, then a copy of the element is returned.
- if the contained type is a struct, then a copy is returned.

That's simple .. but what if the contained type is a class or an array?

Well, if it's a class, then it's a little bit complicated. I don't even know if we /need/ any kind of guarantees with an array of objects, but anyway!
Let's assume that we do need this guarantee, and let's take a step back.
The compiler shouldn't allow the contained type of a read-only array reference to be a class; instead, it should only allow it to be an interface that's derived from a generic (empty) interface called IReadOnly.

This measure will not allow the compiler to always ensure that objects contained in such a way cannot be modified, however, it gives the author of the class a guarantee that if he subclasses IReadOnly the right way, then his objects won't be modifiable.

Example:
------------------
interface IImmutableCircle : IReadOnly
{
    int radius();
}

class Circle : IImmutableCircle
{
   private int mradius;
public:
   int radius() { returm mradius; }
   void radius( int r ) { mradius = r; }
}

....

Circle[$] arr; // error, no class allowed as the contained type for a read-only reference
IImutableCircle[$] arr; //ok, since IImmutableCircle derives from IReadOnly
---------------------------

Of course the coder can mess up his code and add methods in IImmutableCircle that allow the object to be modified, but the important thing is that that's his own reponsibility; no user of his code can mess this up.

If there's a loop-hole in this approach, then disregard it. I'm starting to think that the whole issue of protecting objects is unneeded.

A similar approach can be taken if the contained type is an array.
Either prevent that and require it to be a read-only array reference, or allow it because preventing it is too complicated or just un-needed.

So, what do you think about this proposal?
Is it practical? Does it solve most of the const issues?
Does it even make sense, or is it just stupid all-together?

I was gonna post this as a new topic in the main D ng, but I thought it might have been proposed before, so I present it here instead.

> 
> The one problem with using aggregates in this manner is related to return values. For example, you can make a String struct or class and control what each method does to the encapsulated content. At some point, though, the content will likely need exposing. Perhaps via a toString() method or via some other means. Simply duplicating the content at this point is a contentious issue, so some means of tagging the return value as 'immutable', and having that usage enforced, would seem to be necessary.

I think the above proposal should covers most of that.
The only thing left is adding a toReadOnlyString() to the Object class, or something like that.


A Java-like immutable string type can be declared with
char[$] x; // x is an immutable string!
Well, it's not really immutable, but the reference is read-only, so the string cannot be modified thru that reference.
July 08, 2006
Hasan Aljudy wrote:
[snip]
> Then how about introducing a new type: read-only array reference.
> (The idea is inspired by Java's immutable string class)
> 
> It would be a distinct type, but built into the language core.
> It has a different declaration syntax from regular arrays.
> It cannot be casted to anything at all, absolutly no pointer manipulation is allowed either.
> The content of the array cannot be modified (further explanation below).
> The reference itself *can* be modified to refer to another array, but it would still be a read-only reference.
> Any type of regular array reference (dynamic/static/associative) can be converted to a read-only array reference.

Having a true set of readonly array[] types would certainly resolve all such issues that I've personally encountered with D, although some might balk at having another set of TypeInfo? On the other hand, that may be wholly preferable to implementing a type-modifier instead?

It is also fully backward compatible ;)

[snip other good stuff]

Really don't think any special-cases are required here ~ if a readonly array, of any type, is used as an lValue in any manner, it is a compile-time error. Simple, neat, easy to understand.

What's missing?

* interfacing with extern(C) functions via pointers?

* pointers in general, within D?

I suspect the above could be handled in a minimalist manner? e.g. I suspect we could probably get by without readonly-pointers in D. I use pointers quite a bit as function arguments, but I can't think of a case where an array wouldn't suffice instead (in order to get immutable arguments).

In other words, to simplify things as much as possible we should consider the minimal subset with the most mileage ~ the best bang for the buck

* what else?


July 08, 2006
In article <e8n6v9$2csb$1@digitaldaemon.com>, Hasan Aljudy says...
>
[...]
>I am from a C++/Java background, yet I still don't fully understand const! The only thing I understand is that Java doesn't need it because it's higher-level than D, doesn't allow pointer manipulation, and has builtin immutable String class.
>
>I still don't understand why D needs it, or why do some people think so.
>
[...]
>
>Then how about introducing a new type: read-only array reference. (The idea is inspired by Java's immutable string class)
>
>It would be a distinct type, but built into the language core.
>It has a different declaration syntax from regular arrays.
>It cannot be casted to anything at all, absolutly no pointer
>manipulation is allowed either.
>The content of the array cannot be modified (further explanation below).
>The reference itself *can* be modified to refer to another array, but it
>would still be a read-only reference.
>Any type of regular array reference (dynamic/static/associative) can be
>converted to a read-only array reference.
>
[...]

Except for the object stuff and, for the most part, the different declaration syntax, this is just about the same as the const type I have been wanting. A syntax that says "this array can't be changed" would cover about %95+ of what I want. Extending this to direct access to public members of classes and structs would put it up to %99+.


July 08, 2006
kris wrote:
> Hasan Aljudy wrote:
> [snip]
>> Then how about introducing a new type: read-only array reference.
>> (The idea is inspired by Java's immutable string class)
>>
>> It would be a distinct type, but built into the language core.
>> It has a different declaration syntax from regular arrays.
>> It cannot be casted to anything at all, absolutly no pointer manipulation is allowed either.
>> The content of the array cannot be modified (further explanation below).
>> The reference itself *can* be modified to refer to another array, but it would still be a read-only reference.
>> Any type of regular array reference (dynamic/static/associative) can be converted to a read-only array reference.
> 
> Having a true set of readonly array[] types would certainly resolve all such issues that I've personally encountered with D, although some might balk at having another set of TypeInfo? On the other hand, that may be wholly preferable to implementing a type-modifier instead?
> 
> It is also fully backward compatible ;)
> 
> [snip other good stuff]
> 
> Really don't think any special-cases are required here ~ if a readonly array, of any type, is used as an lValue in any manner, it is a compile-time error. Simple, neat, easy to understand.

A ReadOnly array would still need to access the contents of a standard array for this to be useful, so it couldn't be completely excluded from evaluation as an lvalue--initializations would be exempt.


Sean
July 08, 2006

Sean Kelly wrote:
> kris wrote:
> 
>> Hasan Aljudy wrote:
>> [snip]
>>
>>> Then how about introducing a new type: read-only array reference.
>>> (The idea is inspired by Java's immutable string class)
>>>
>>> It would be a distinct type, but built into the language core.
>>> It has a different declaration syntax from regular arrays.
>>> It cannot be casted to anything at all, absolutly no pointer manipulation is allowed either.
>>> The content of the array cannot be modified (further explanation below).
>>> The reference itself *can* be modified to refer to another array, but it would still be a read-only reference.
>>> Any type of regular array reference (dynamic/static/associative) can be converted to a read-only array reference.
>>
>>
>> Having a true set of readonly array[] types would certainly resolve all such issues that I've personally encountered with D, although some might balk at having another set of TypeInfo? On the other hand, that may be wholly preferable to implementing a type-modifier instead?
>>
>> It is also fully backward compatible ;)
>>
>> [snip other good stuff]
>>
>> Really don't think any special-cases are required here ~ if a readonly array, of any type, is used as an lValue in any manner, it is a compile-time error. Simple, neat, easy to understand.
> 
> 
> A ReadOnly array would still need to access the contents of a standard array for this to be useful, so it couldn't be completely excluded from evaluation as an lvalue--initializations would be exempt.
> 
> 
> Sean

It's actually an array "reference" .. you can make it refer to (point to) any normal array, i.e. you can change what it refers to.
You just can't use that reference to change the properties or contents of the array.
You can use it to read the contents of the array it refers to.

Think of it as an interface with read-only methods and no write methods.
July 08, 2006
Derek Parnell wrote:
> I'm not from a C++/C#/Java background, so please excuse my lack of understanding about the meaning that is being applied to the term 'const' in these recent discussions.
> 

I think many times people talked a bit vaguely with their meaning of const.

> To me, there seems to be two things being talked about.
> 
> (a) Data, which once initialized, is not to be modified for the run-time life of the application.
> 
> (b) Data, which once passed to some function, is not to be modified for the run-time life of that function.
> 
> Walter's proposed refinement of the 'in' keyword does nothing for type (a), and only limited support for type (b), in that it protects data from the called function but not from functions that that subsequently calls. It is only protection for one level deep. And the only data protected is class objects and not other reference types.
> 
> Is there any other types (or subtypes) of 'const' meanings being discussed or considered?
> 
> For example, are we distinguishing between compile-time protection and run-time protection?
> 

'const', in a general sense, is a mechanism to specify whether a variable/data/object can or can not modified, and enforce that contract (at compile time). 'const' is usually in the sense of (b), that is, some parts of code may modify the data, while others can only read it (thus it is used for ownership management). That's the case for C++.
Enforcing the contract means you cannot assign a const variable to a non-const one, or similarly, pass a const variable to a function that expects a non-const argument. The only way to subvert this is with a cast (which should be the only way to subvert anything).

There are some variations in const semantics. In C++, const is a type-modifier, meaning that const can be applied to each type element, and not the "variable as whole". Best to give an example. In C++ you can have:
  const int * iptr = ...;
  int const * iptr = ...;
  const int const * iptr = ...;
each with different meanings:

  const int * iptr = ...;
  // cannot modify the pointed int, can modify the pointer

  int const * iptr = ...;
  // can modify the pointed int, cannot modify the pointer (the pointer is const)

  const int const * iptr = ...;
  // Cannot modify the pointed int, nor cannot modify the pointer

In this usual meaning (C++), there are no guarantees that the data will not actually change (by someone else for example) or that it is a compile constant. (That is why I say the use of this notion of const is for ownership management).

In D, 'const' is not a type modifier but what Walter calls a "storage modifier" (or storage attribute), but I think "variable modifier" is perhaps a better term. D's const is applied not to each of many possible type elements, but to the whole variable, like private or other protection attributes (and as such there can be only one const per declaration). D's const also has two different meanings (a bad thing IMO), and they're both different from C++'s:

* const var declaration with an initializer:
-> the value of the variable is a compile time constant. The variable has no storage, it becomes an alias for it's initializer literal. (and has such one can't take the address of it)

* const var declaration without an initializer:
-> the var can be initialized in constructors only, and on all other places it's value is read-only. The variable has normal storage. This is what is (much more properly) called 'final' in other languages.

There are some more possible variations. There can be a const that has the same meaning as C++'s (you cannot change the var), but which is a variable modifier instead of a type modifier. But in this case there is a prominent issue of whether the read-only/immutability property is transitive or not. For example (calling this behavior 'readonly'):
  readonly int **ptr;
Can one change *ptr and **ptr ? Or just ptr?

And there are quite some more issues to consider when implementing a 'const' mechanism such as this one. (see below)

> My requirements for 'const' are almost covered by Walter's new proposal. I'm a quite concerned that if I tell Foo() that it can't change something, that Foo() can still tell Bar() to disregard my request and tell Bar() that it's okay to change it anyway.
> 
> I think that apart from array references, type (a) const can be acheived through using private members and public properties. I'm not sure how we can fully implement (a) with current D semantics.
> 
> --Derek Parnell
> Melbourne, Australia

I'm assuming that in that that last "(a)" you meant "(b)".
Implementing a mechanism such as this is actually quite complex (in terms of design itself) because of several special cases which need more language constructs. It's not just adding the "immutable" keyword as some people seem to think.
To know what I'm talking about exactly one should read this quite informative paper:
http://pag.csail.mit.edu/pubs/ref-immutability-oopsla2005-abstract.html
I haven't read it all yet, but I plan to do so soon, since everyone is talking about const again. And I would say reading it should likely be mandatory for anyone who wants to venture thinking and posting how the const system should work. It describes the issues one faces when implementing such a system, and the reference immutability system described there is perhaps a good starting point for a system for D.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 08, 2006
Bruno Medeiros wrote:
> Derek Parnell wrote:
> 
>> I'm not from a C++/C#/Java background, so please excuse my lack of understanding about the meaning that is being applied to the term 'const' in these recent discussions.
>>
> 
> I think many times people talked a bit vaguely with their meaning of const.
> 
>> To me, there seems to be two things being talked about.
>>
>> (a) Data, which once initialized, is not to be modified for the run-time life of the application.
>>
>> (b) Data, which once passed to some function, is not to be modified for the run-time life of that function.
>>
>> Walter's proposed refinement of the 'in' keyword does nothing for type (a), and only limited support for type (b), in that it protects data from the called function but not from functions that that subsequently calls. It is only protection for one level deep. And the only data protected is class objects and not other reference types.
>>
>> Is there any other types (or subtypes) of 'const' meanings being discussed or considered?
>>
>> For example, are we distinguishing between compile-time protection and run-time protection?
>>
> 
> 'const', in a general sense, is a mechanism to specify whether a variable/data/object can or can not modified, and enforce that contract (at compile time). 'const' is usually in the sense of (b), that is, some parts of code may modify the data, while others can only read it (thus it is used for ownership management). That's the case for C++.
> Enforcing the contract means you cannot assign a const variable to a non-const one, or similarly, pass a const variable to a function that expects a non-const argument. The only way to subvert this is with a cast (which should be the only way to subvert anything).
> 
> There are some variations in const semantics. In C++, const is a type-modifier, meaning that const can be applied to each type element, and not the "variable as whole". Best to give an example. In C++ you can have:
>   const int * iptr = ...;
>   int const * iptr = ...;
>   const int const * iptr = ...;
> each with different meanings:
> 
>   const int * iptr = ...;
>   // cannot modify the pointed int, can modify the pointer
> 
>   int const * iptr = ...;
>   // can modify the pointed int, cannot modify the pointer (the pointer is const)
> 
>   const int const * iptr = ...;
>   // Cannot modify the pointed int, nor cannot modify the pointer
> 

There's another place you can put 'const' in C++:

class A {
    void bar(int i);
    int foo() const;
};

This "const" ensures that the member function A::foo does not modify the instance of A that you are calling it on. (If the function does do so, it is a compile error.) This is an issue when you are dealing with const instances of A:

const A a;

a.bar(12); // ERROR! a is const, A::bar is not
a.foo();   // Okay

I actually view this as necessary if we get a way to declare an instance as immutable in D. (Honestly, I have few issues with C++ const, though this "const-by-default for class instances" idea has merit, too.)

> In this usual meaning (C++), there are no guarantees that the data will not actually change (by someone else for example) or that it is a compile constant. (That is why I say the use of this notion of const is for ownership management).
> 
> In D, 'const' is not a type modifier but what Walter calls a "storage modifier" (or storage attribute), but I think "variable modifier" is perhaps a better term. D's const is applied not to each of many possible type elements, but to the whole variable, like private or other protection attributes (and as such there can be only one const per declaration). D's const also has two different meanings (a bad thing IMO), and they're both different from C++'s:
> 
> * const var declaration with an initializer:
> -> the value of the variable is a compile time constant. The variable has no storage, it becomes an alias for it's initializer literal. (and has such one can't take the address of it)
> 
> * const var declaration without an initializer:
> -> the var can be initialized in constructors only, and on all other places it's value is read-only. The variable has normal storage. This is what is (much more properly) called 'final' in other languages.
> 
> There are some more possible variations. There can be a const that has the same meaning as C++'s (you cannot change the var), but which is a variable modifier instead of a type modifier. But in this case there is a prominent issue of whether the read-only/immutability property is transitive or not. For example (calling this behavior 'readonly'):
>   readonly int **ptr;
> Can one change *ptr and **ptr ? Or just ptr?
> 
> And there are quite some more issues to consider when implementing a 'const' mechanism such as this one. (see below)
> 
>> My requirements for 'const' are almost covered by Walter's new proposal. I'm a quite concerned that if I tell Foo() that it can't change something, that Foo() can still tell Bar() to disregard my request and tell Bar() that it's okay to change it anyway.
>>
>> I think that apart from array references, type (a) const can be acheived through using private members and public properties. I'm not sure how we can fully implement (a) with current D semantics.
>>
>> --Derek Parnell
>> Melbourne, Australia
> 
> 
> I'm assuming that in that that last "(a)" you meant "(b)".
> Implementing a mechanism such as this is actually quite complex (in terms of design itself) because of several special cases which need more language constructs. It's not just adding the "immutable" keyword as some people seem to think.
> To know what I'm talking about exactly one should read this quite informative paper:
> http://pag.csail.mit.edu/pubs/ref-immutability-oopsla2005-abstract.html
> I haven't read it all yet, but I plan to do so soon, since everyone is talking about const again. And I would say reading it should likely be mandatory for anyone who wants to venture thinking and posting how the const system should work. It describes the issues one faces when implementing such a system, and the reference immutability system described there is perhaps a good starting point for a system for D.
> 


-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://dsource.org/projects/pyd/wiki
July 08, 2006
Bruno Medeiros wrote:
> There are some variations in const semantics. In C++, const is a
> type-modifier, meaning that const can be applied to each type element,
> and not the "variable as whole". Best to give an example. In C++ you can
> have:
>   const int * iptr = ...;
>   int const * iptr = ...;
>   const int const * iptr = ...;
> each with different meanings:
> 
>   const int * iptr = ...;
>   // cannot modify the pointed int, can modify the pointer
> 
>   int const * iptr = ...;
>   // can modify the pointed int, cannot modify the pointer (the pointer
> is const)
> 
>   const int const * iptr = ...;
>   // Cannot modify the pointed int, nor cannot modify the pointer
> 

Actually, the former two are equivalent. To clarify (equivalent types are paired
on one line):

const int, int const
const int *, int const *
const int * const, int const * const
int * const

There's only one way to write that last one: a constant pointer to a non-constant integer.

This is why I always write "const" second when writing C(++): it'd be inconsistent with the way const pointers are written out to do otherwise. Plus, they can be read right-to-left more easily. ("const int * const" reads as "constant pointer to an integer --- no, wait, a constant integer" to me <g>)
« First   ‹ Prev
1 2 3