 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Le Chaud Lapin Guest
|
Posted: Sun Nov 27, 2005 4:06 am Post subject: Semantic Regularity For Regularity's Sake |
|
|
Hi All,
I mentioned in a concurrent post that I am testing Microsoft's new
Visual C++ express compiler on a large code base. I got thousands of
errors on code I thought was mostly "pure" C++, as it compiled without
complaint with Visual C++ 7.1. The errors are my fault - looking at
top of page 394, TCPPPL 3rd Ed., it states (more or less), that you
cannot, for example, do things like this:
struct Outer
{
struct Inner
{
} ;
} ;
using Outer::Inner;
Inner i; // not allowed to pull out typename from Outer. must use
explicty qualification:
Outer::Inner i;
One of the other comformance improvements that the new compiler made
was to force explicit attachment of an ampersand (&) to the name of a
member function, if what was meant is to specify the address of the
member function.
Instead of this:
insert (SERVICE_CODE_FILE_BIND,
file_bind);
insert (SERVICE_CODE_FILE_COPY,
file_copy);
insert (SERVICE_CODE_FILE_DESTROY,
file_destroy);
insert (SERVICE_CODE_FILE_FREE,
file_free);
One must write this:
insert (SERVICE_CODE_FILE_BIND,
&file_bind);
insert (SERVICE_CODE_FILE_COPY,
&file_copy);
insert (SERVICE_CODE_FILE_DESTROY,
&file_destroy);
insert (SERVICE_CODE_FILE_FREE,
&file_free);
It's always been my opinion that the second form is better because it
supports more "regular thinking" than the first form. If one intends
to say "the address of the function", even though there appears to be
no use for the name of the function alone in the language, then that
should be what one writes. if I had designed the syntax, I would have
forced inclusion of the ampersand from the outset, because the first
method constitutes a breach in regular thought. It's a somewhat minor
breach, but a breach nevertheless. In any case, it's not minor any
more. I have 260 lines of code that say so.
There is one other important area where this "breach of regular
thinking" is made: arrays.
void foo (char *);
char x[128];
foo (x); // works but represents breach of regular thinking
foo (&x[0]); // more verbose, but concurs with regular thought,
therefore less mental tax
I would not have allowed the first form to mean what it currently
means. IMO, if there is any big, out-in-your-face flaw in C, it's the
help that the compiler gives to you with arrays. How hard is it to
write &x[0]? Only a few more characters, and the benefit from the
consistency is invaluable, especially to beginners. Also, as
programmers, we might have benefited from the semantic distinction that
would have remained:
typedef char Cipher_Block[128];
Cipher_Block x, y;
x = y; // no memcpy necessary. one can almost assume optimality from
compiler.
void bar (Cipher_Block block) // copies the entire block to function,
knows that it must be exactly 128 chars or will issue error
void bar (Cipher_Block &block) // block passed by reference. still must
be 128 chars
You get the idea: subscription to regularity for regularity's sake
will often yield small but benefiical fruit and will almost always have
less mental tax. I do ntot think that no apparent immediate benefit
for maintaining semantic distinction (and gaining optimization in
keystrokes as a result of blurring the distinction) is a good excuse to
deviate from this principle.
-Le Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Sun Nov 27, 2005 5:55 pm Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
* Le Chaud Lapin:
| Quote: |
[snip]
There is one other important area where this "breach of regular
thinking" is made: arrays.
void foo (char *);
char x[128];
foo (x); // works but represents breach of regular thinking
foo (&x[0]); // more verbose, but concurs with regular thought,
therefore less mental tax
I would not have allowed the first form to mean what it currently
means. IMO, if there is any big, out-in-your-face flaw in C, it's the
help that the compiler gives to you with arrays. How hard is it to
write &x[0]? Only a few more characters, and the benefit from the
consistency is invaluable, especially to beginners.
|
Let's denote the implicit conversion of an array x to pointer to its
first element, by $(x).
foo(x) is then really foo($(x)).
x[0] is then really *($(x)+0).
And foo(&x[0]) is then really foo(&*($(x)+0)), by definition of
indexing.
As you can see your proposal is to make indexing a fundamental operation
so that it doesn't require a $ in there.
| Quote: | Also, as
programmers, we might have benefited from the semantic distinction that
would have remained:
typedef char Cipher_Block[128];
Cipher_Block x, y;
x = y; // no memcpy necessary. one can almost assume optimality from
compiler.
void bar (Cipher_Block block) // copies the entire block to function,
knows that it must be exactly 128 chars or will issue error
void bar (Cipher_Block &block) // block passed by reference. still must
be 128 chars
|
I don't agree that those examples show any benefit.
The copying examples can be implemented in the current language by
'struct Cipher_Block{ char elem[128]; };', and the pass by reference is
supported by the language as-is also for a raw array,
void bar( Cipher_Block const& block )
On the other hand, one problem with representing an array by a pointer
to its first element (as is the case now) is that this breaks the C++
type system by allowing a Derived* to be used where an array of Base is
expected.
Simply making the $ operation explicit wouldn't solve that: I think
pointer arithmetic would have to be removed to make it impractical to
represent arrays by pointers to their first elements.
But then it would be difficult to do things like using a pointer to some
array element as if it were a pointer to a complete array.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Sun Nov 27, 2005 9:52 pm Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
Le Chaud Lapin wrote:
| Quote: | struct Outer
{
struct Inner
{
} ;
} ;
using Outer::Inner;
|
The obvious solution here is
typedef Outer::Inner Inner;
| Quote: | [...]
typedef char Cipher_Block[128];
Cipher_Block x, y;
x = y; // no memcpy necessary. one can almost assume optimality from
compiler.
void bar (Cipher_Block block) // copies the entire block to function,
knows that it must be exactly 128 chars or will issue error
|
Unfortunately, the language doesn't work like this - built-in arrays
are broken! Another problem is that
Cipher_Block* pCB = new Cipher_Block;
will not compile, and while
char* pc = new Cipher_Block;
compiles, it requires 'delete[] pc;' rather than 'delete pc;'.
The moral is that hiding built-in arrays in typedefs is best avoided,
and something like
typedef boost::array<char, 128> Cipher_Block;
should be used instead. This will support assignment, passing by
value and usual new/delete semantics, and additionally provides
an STL container like interface with (const_)iterator, begin(),
end(), size(). I believe it is proposed to become part of the next
revision's C++ Standard library.
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Mon Nov 28, 2005 8:25 am Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
Alf P. Steinbach wrote:
| Quote: | And foo(&x[0]) is then really foo(&*($(x)+0)), by definition of
indexing.
As you can see your proposal is to make indexing a fundamental operation
so that it doesn't require a $ in there.
|
I do not understand what you mean to say here.
| Quote: | void bar (Cipher_Block &block) // block passed by reference. still must
be 128 chars
I don't agree that those examples show any benefit.
|
The benefit is subtle and somewhat intangible, as I tried to convey in
the title of the thread. The mental burden of my hypothetical
semantics is less than the standard semantics, IMHO.
| Quote: | The copying examples can be implemented in the current language by
'struct Cipher_Block{ char elem[128]; };', and the pass by reference is
supported by the language as-is also for a raw array,
|
Yes, this what I normally do, but again, even if there were no
practical obvious benefits, I still would have prescribed the
alternative method because it seems to present less mental tax - read -
it is more regular.
| Quote: |
Simply making the $ operation explicit wouldn't solve that: I think
pointer arithmetic would have to be removed to make it impractical to
represent arrays by pointers to their first elements.
But then it would be difficult to do things like using a pointer to some
array element as if it were a pointer to a complete array.
|
Still not sure I understand what you mean here.
-Le Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Mon Nov 28, 2005 3:59 pm Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
* Le Chaud Lapin:
| Quote: |
Alf P. Steinbach wrote:
And foo(&x[0]) is then really foo(&*($(x)+0)), by definition of
indexing.
As you can see your proposal is to make indexing a fundamental operation
so that it doesn't require a $ in there.
I do not understand what you mean to say here.
|
Consider: in the case of semantically regular notation you can't write
p = a; // Decay.
But you can write
p = &a[0];
With the current language definition that is equivalent to
p = & *(a + 0);
which involves and is based on the decay just made illegal.
Therefore the semantically regular notation must have some other
definition of indexing, a definition that isn't based on the decay.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Tue Nov 29, 2005 10:23 am Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
Alf P. Steinbach wrote:
| Quote: | Consider: in the case of semantically regular notation you can't write
p = a; // Decay.
But you can write
p = &a[0];
With the current language definition that is equivalent to
p = & *(a + 0);
which involves and is based on the decay just made illegal.
Therefore the semantically regular notation must have some other
definition of indexing, a definition that isn't based on the decay.
|
I think I understand. The decay is what I was arguing against. I
would not have allowed it any context, but required and explict
address-of operation each time. So in the semantically regular
notation, I would not have allowed:
p = a; // p is pointer, a is array, no assignment allowed.
But I would have allowed:
a1 = a1; // a1 and a2 are both arrays of same type so assignment is
allowed.
As far as taking the address of the 5th element, I would have forced:
p = &a[4];
One benefit that comes to mind of allowing assignment of arrays is
that you can write ultra-fast portable memory-copy code.
-Le Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Nov 30, 2005 11:00 am Post subject: Re: Semantic Regularity For Regularity's Sake |
|
|
Le Chaud Lapin wrote:
| Quote: | Alf P. Steinbach wrote:
Consider: in the case of semantically regular notation you
can't write
p = a; // Decay.
But you can write
p = &a[0];
With the current language definition that is equivalent to
p = & *(a + 0);
which involves and is based on the decay just made illegal.
Therefore the semantically regular notation must have some
other definition of indexing, a definition that isn't based
on the decay.
I think I understand. The decay is what I was arguing against.
|
Your subject line mentionned semantic regularity. I presumed
that you're real desire was that arrays worked like any other
type in C++, and weren't second class types -- effectively
broken, as Falk says. This would mean no decay, of course, but
also real value semantics, assignment between arrays of like
types, etc. What you get with std::vector, and what you get
with arrays in most other languages with value semantics.
While the current situation of arrays is obviously an anomaly,
and poor language design, there is a long history behind it. It
definitly made sense in B, for example, and C more or less took
over the semantics of B at the beginning (and there weren't any
other composite types to compare it with). Today, history and
an enormous body of existing code means that it cannot be
changed. We have to live with it, even though I doubt you'll
find many people who consider it a good solution.
| Quote: | I would not have allowed it any context, but required and
explict address-of operation each time. So in the
semantically regular notation, I would not have allowed:
p = a; // p is pointer, a is array, no assignment allowed.
But I would have allowed:
a1 = a1; // a1 and a2 are both arrays of same type so assignment is
allowed.
As far as taking the address of the 5th element, I would have forced:
p = &a[4];
|
And the type of &a would be a pointer to an array, and not a
pointer to the first element, e.g. int (*)[], and not int*.
| Quote: | One benefit that comes to mind of allowing assignment of
arrays is that you can write ultra-fast portable memory-copy
code.
|
Another is simply orthogonality. Easier to teach, easier to
understand, and ... easier to use in generic code: no problem
with things like: T* = new T.
Note that when C++'s references do treat arrays as first class
objects.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|