Topic: Proposed extension to STL containers
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/09/21 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>
>sizeof(array)/sizeof(element) shall only be used to determine the number
>of elements in an array immediately after the declaration. For example:
>
>int array[]={1, 2, 3, 5, 7, 11, 13};
>int const array_size = sizeof(array)/sizeof(int);
Why not forbid it entirely? We know a safe mechanism. Given the
declaration:
template <typename T, size_t N>
char (& sizer(T (&array)[N])[N]; // not defined
then use:
int array[]={1, 2, 3, 5, 7, 11, 13};
int const array_size = sizeof(sizer(array));
This will only work if array really is an array, and not just a pointer.
Furthermore, it's shorter and it stays correct when you change the type
of the array elements. (Siemel Naran and Mark Williams came by this
formulation independently, based on work by Dietmar Kuehl and me.)
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/21 Raw View
In article <6tpgu5$jvm$1@shell7.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>This will only work if array really is an array, and not just a pointer.
>Furthermore, it's shorter and it stays correct when you change the type
>of the array elements. (Siemel Naran and Mark Williams came by this
>formulation independently, based on work by Dietmar Kuehl and me.)
Fine, as long as you do not need to use your code in C where there are
no templates. There are still numerous programmers using C (and some of
them use C++ as well:)
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/09/21 Raw View
Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
><ncm@nospam.cantrip.org> writes
>>This will only work if array really is an array, and not just a pointer.
>>Furthermore, it's shorter and it stays correct when you change the type
>>of the array elements. (Siemel Naran and Mark Williams came by this
>>formulation independently, based on work by Dietmar Kuehl and me.)
>
>Fine, as long as you do not need to use your code in C where there are
>no templates. There are still numerous programmers using C (and some of
>them use C++ as well:)
People using C can define a macro:
#ifdef __cplusplus
template <typename T, int N> char (& sizer(T (&)[N]))[N];
# define ARRAYSIZE(a) (sizeof(sizer(a)))
#else
# define ARRAYSIZE(a) (sizeof(a)/sizeof(*a))
#endif
This works in a C header, but provides additional protection for C++.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/17 Raw View
In article <6tk3ec$v2f$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com
writes
>As for the "Magic Numbers" concept: I don't see a huge amount of
>difference between
> #define NAME_LENGTH 24 // or extern const int NAME_LENGTH =3D 24;
> char name[NAME_LENGTH]
>and
> char name[24];
> #define NAME_LENGTH sizeof(name)/sizeof(name[0])
Don't you? Oh well, it takes all sorts.
BTW you will never find me using your choices in C++. I have a strong
aversion to unnecessary uses of the preprocessor, and of writing
identifiers in all upper case unless they are pre-processor ones. In my
code all upper case means 'extreme caution, what you see is not what the
compiler sees.' Also I agree with Dan Saks as to the placement of const
so:
either:
int const name_length =3D 24;
or
enum {name_length =3D 24};
I prefer the latter but will live with the former.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/09/17 Raw View
In article <$+U6DGAonN$1Ewgc@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>But it also fails for dynamic arrays. If you never use globals and
>always keep your functions to one page the mechanism would be relatively
>safe. However, in such circumstances, what would be the point of using
>it? Statically declared arrays should always use a manifest constant
>for their dimension so you will know the size. Please give me an
>example of a piece of code where the mechanism is actually useful rather
>than being a paliative for those who insist on salting their code with
>magic numbers.
It is intended for those that want to avoid salting their code with
magic numbers. Look at the following code-fragment:
int tryprimes[]=3D{2,3,5,7,11,13,15,17,19,21};
const int numprimes=3Dsizeof(tryprimes)/sizeof(tryprimes[0]);
for(i=3D0;i<numprimes;i++) {
if (f(tryprimes[i])) cout<<"Found prime:"<<i<<endl;
};
Manually counting the number of initializers to tryprimes is
error-prone (especially if it is something we often change), whereas
explicit declarations such as:
int tryprimes[11]=3D{2,3,5,7,11,13,15,17,19,21};
are legal, but don't catch mismatches between number of initializers
and array size.
The sizeof(x)/sizeof(x[0]) trick is the normal way of handling this in C.
Using explicit end-of-sequence terminator is another way, and perhaps
some better alternative using templates could be found.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/17 Raw View
In article <35FDBA16.446B@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>Using a statically declared constant for the size of this table would
>make changing the number of entries slightly more complicated, with no
>corresponding benefit that I can see.
I agree, but, as always, guidelines are not absolute rules. The expert
knows when to do it differently. Unfortunately I have seen an awful lot
of code broken because the author just uses mechanisms without
understanding. Providing a macro just about ensures that this will
happen.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/17 Raw View
> >AllanW@my-dejanews.com wrote:
> >> How many of us have written 10 or more
> >> programs in a row without using this construct:
> >> (sizeof(x)/sizeof(x[0]))
> In article <35DC60CA.794B@wizard.net> James Kuyper <kuyper@wizard.net>
writes:
> >I'd like to know why this has never been made a standard macro.
In article <6tcvlf$okh@panix.com>,
comeau@comeaucomputing.com wrote:
> A few (briefly stated) reasons, including, but not limited to:
> * It's easy to do yourself (of course, it's easy to be provided too)
> * The C committee was mainly codifying existing practice
> (often of implementations, rather than of programmers/code).
> * The C++ committee was inventive, but more on issues of techniques and
> programming styles. In one light on "more important issues". Oddly,
> some of those things (templates, classes, STL, etc) can be used in
> alternatives for the construct.
> * It does not work on all arrays (for instance, array parameters).
> * Weak?: for some, say with multi-dimensional array, it will probably be
> invoked incorrectly often, or with dynamically allocated arrays too.
> * Even at the "C level", in the grand scheme of things, the above is not
> the only candidate construct possible. For instance, it can be debated
> that a standard macro which computes the address of the last element
> (or one past the last element) is more valuable, or that positional
> sentinal values can sometimes be more important than sizes. And so on
> for other such pathology.
And which of these problems is solved or avoided by requiring the
user to #define the macro herself, if used at all?
Is there some better alternative to this macro, which avoids all or
at least some of these problems?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----=3D=3D Posted via Deja News, The Leader in Internet Discussion =3D=3D=
-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/09/17 Raw View
In article <vqe+m8AD5p$1Ewjx@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>
> In article <6tm11t$56j$1@nnrp1.dejanews.com>, jkanze@otelo.ibmmail.com
> writes
> >I do. Compare the following two bits of code:
>
> > static int const lengthX =3D 7 ;
> > static int const x[ lengthX ] =3D
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
>
> >and
>
> > static int const x[] =3D
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
> > static int const lengthX =3D sizeof( x ) / sizeof( x[ 0 ] ) ;
>
> >One, of course, is wrong.
>
> Oh! Which one? Yes I know lengthX evaluates to 6 in the second case
> but the array has seven elements in the first, it is just that the last
> one is 0.
The elements of the second array also form a Fibonicci series; those of
the first don't.
I would contend that the first form is either wrong, or misleading, since
on looking at it, the immediate impression is that its elements form a
Fibonicci series. It it is supposed to, then it is wrong, and if it is
not supposed to, then you really should write the final 0 out, so the use=
r
will notice.
This usage will become even more important if and when C++ adds the
designated initializers of C. How would you write the following, without
knowing the numeric values of the enum constants:
static char const* const
labels[] =3D
{
[ ENUM1 ] =3D "enum1" ,
[ ENUM2 ] =3D "enum2" ,
// ...
} ;
static int const numberOfLabels
=3D sizeof( labels ) / sizeof( labels[ 0 ] ) ;
(Obviously, when using such a table, one must 1) do a bounds check using
numberOfLabels before accessing, and 2) check for NULL after accessing.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient=E9e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----=3D=3D Posted via Deja News, The Leader in Internet Discussion =3D=3D=
-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/17 Raw View
In article <vqe+m8AD5p$1Ewjx@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>
> In article <6tm11t$56j$1@nnrp1.dejanews.com>, jkanze@otelo.ibmmail.com
> writes
> >I do. Compare the following two bits of code:
>
> > static int const lengthX = 7 ;
> > static int const x[ lengthX ] =
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
>
> >and
>
> > static int const x[] =
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
> > static int const lengthX = sizeof( x ) / sizeof( x[ 0 ] ) ;
>
> >One, of course, is wrong.
>
> Oh! Which one?
The first one, naturally.
> Yes I know lengthX evaluates to 6 in the second case
> but the array has seven elements in the first, it is just that the last
> one is 0.
Yes. What you're saying is that both code snippets are well defined.
But "well defined" is not the same as "correct."
If the programmer really did want the last element to be 0, he should
have said so. Possibly with a comment, but preferably with a constant
in the initializer-list. (Since 6 out of 7 values are already specified,
this doesn't seem unreasonable.) But there was neither a 7th
initializer nor a comment, so I feel justified by insisting that the
code should be fixed (again, possibly with a comment -- but certainly
DON'T leave it exactly as is!).
The second version of the code snippet goes out of it's way to avoid
magic numbers, by computing the size automatically. The debate shown
above is impossible. Clearly, what the programmer meant is what the
compiler will do.
The compiler, noticing (as you did) that both versions are well-defined,
will not even issue a warning for either version.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1998/09/17 Raw View
In article <6tln3m$s2m$1@news.lth.se>, Email_To::.Hans.Olsson@dna.lth.se
(Hans Olsson) wrote:
> Manually counting the number of initializers to tryprimes is
> error-prone (especially if it is something we often change), whereas
> explicit declarations such as:
>
> int tryprimes[11]={2,3,5,7,11,13,15,17,19,21};
>
> are legal, but don't catch mismatches between number of initializers
> and array size.
That is a really unfortunate property of C/C++. I think that in almost
every case you would have
a. An array without initialisation data.
b. A large array with the first few members initialised
c. An array with ALL members initialised.
A while ago, I used a compiler that would produce a warning if you used a
switch () statement based on an enum value, and you supplied cases for
most, but not all enums. The same could probably be done for array and
struct initialisation: Give a warning if most, but not all, array elements
are initialised.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/14 Raw View
In article <$+U6DGAonN$1Ewgc@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>
> In article <35FC56E7.15FB@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >For exactly the same reason, and in exactly the same sense, sizeof()
> >doesn't work on them either. However, I consider that to be an
> >inappropriate definition of 'work'. It does exactly what I would expect
> >it to do on array parameters, which is why I would never use it on them.
>
> But it also fails for dynamic arrays. If you never use globals and
> always keep your functions to one page the mechanism would be relatively
> safe. However, in such circumstances, what would be the point of using
> it? Statically declared arrays should always use a manifest constant
> for their dimension so you will know the size. Please give me an
> example of a piece of code where the mechanism is actually useful rather
> than being a paliative for those who insist on salting their code with
> magic numbers.
void inline my_Copy(char*out, const char*in, int outlen, int inlen) {
// Prevents common error of passing pointer instead of array reference
// Note this also blocks valid but rare case of very short buffers
assert(outlen != sizeof(out) && inlen != sizeof(in));
// Copy from input string, until end of string or until output full
for (; outlen>1 && inlen>0 && *in; --outlen,--inlen)
*(out++) = *(in++);
// Null terminate
(*out) = '\0';
}
#define myCopy(a,b) my_Copy(a,b,sizeof(a),sizeof(b))
Usage:
myCopy(newName, oldName);
myCopy(newAddress1, oldAddress1);
myCopy(newAddress2, oldAddress2);
myCopy(newCity, oldCity); // ...etc...
Note that oldName and newName don't have to be the same length; myCopy
will automatically copy as much as possible, while still null-terminating
oldName. (Unlike strncpy, which is not only harder to call, but may also
leave oldName without a null terminator.) Presumably newName and oldName
were both declared with manifest constants for their lengths, but we
don't have to repeat them here.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/09/15 Raw View
Francis Glassborow wrote:
>
> In article <35FC56E7.15FB@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >For exactly the same reason, and in exactly the same sense, sizeof()
> >doesn't work on them either. However, I consider that to be an
> >inappropriate definition of 'work'. It does exactly what I would expect
> >it to do on array parameters, which is why I would never use it on them.
>
> But it also fails for dynamic arrays. If you never use globals and
Again, 'fails' seems inappropriate; it gives exactly the result I would
expect it to give for dynamic arrays, which is why I wouldn't use it on
dynamic arrays. However, I would use it for an array of dynamic arrays:
int *ap[]={array1, array2, array3};
sizeof(ap)/sizeof(ap[0]) gives 3, which is a useful number to know when
using ap.
> always keep your functions to one page the mechanism would be relatively
> safe. However, in such circumstances, what would be the point of using
> it? Statically declared arrays should always use a manifest constant
> for their dimension so you will know the size. Please give me an
> example of a piece of code where the mechanism is actually useful rather
> than being a paliative for those who insist on salting their code with
> magic numbers.
Here's a simplified version of a piece of actual C code where I've used
it. I've left out (lots of) details that are irrelevant to this
question:
========================================================================
#define ELEMENTS(a) (int)(sizeof(a)/sizeof(a[0]))
#include "GEO_product.h"
/* #defines many macros used to initialize SDS_list */
static struct{
char * name; /* Name of the SDS */
int count; /* Count of entries */
/* Six other members cut for sake of clarity. */
} SDS_list[] = {
{EVTIME, 1},
{MSIDE, 1},
/* lots more entries. */
{GFLAGS, 10}
};
for(i=0; i<ELEMENTS(SDS_list); i++)
{
/* Process SDS_list[i] */
}
========================================================================
Using a statically declared constant for the size of this table would
make changing the number of entries slightly more complicated, with no
corresponding benefit that I can see.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/09/15 Raw View
In article <6tk3ec$v2f$1@nnrp1.dejanews.com>,
AllanW@my-dejanews.com wrote:
>
> In article <$+U6DGAonN$1Ewgc@robinton.demon.co.uk>,
> Francis Glassborow <francis@robinton.demon.co.uk> wrote:
> > Please give me an
> > example of a piece of code where the mechanism is actually useful rather
> > than being a paliative for those who insist on salting their code with
> > magic numbers.
>
> As for the "Magic Numbers" concept: I don't see a huge amount of
> difference between
> #define NAME_LENGTH 24 // or extern const int NAME_LENGTH = 24;
> char name[NAME_LENGTH]
> and
> char name[24];
> #define NAME_LENGTH sizeof(name)/sizeof(name[0])
I do. Compare the following two bits of code:
static int const lengthX = 7 ;
static int const x[ lengthX ] =
{
1 , 1 , 2 , 3 , 5 , 8
} ;
and
static int const x[] =
{
1 , 1 , 2 , 3 , 5 , 8
} ;
static int const lengthX = sizeof( x ) / sizeof( x[ 0 ] ) ;
One, of course, is wrong.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: rdamon@BeltronicsInspection.com (Richard Damon)
Date: 1998/09/15 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>In article <35FC56E7.15FB@wizard.net>, James Kuyper <kuyper@wizard.net>
>writes
>>For exactly the same reason, and in exactly the same sense, sizeof()
>>doesn't work on them either. However, I consider that to be an
>>inappropriate definition of 'work'. It does exactly what I would expect
>>it to do on array parameters, which is why I would never use it on them.
>
>But it also fails for dynamic arrays. If you never use globals and
>always keep your functions to one page the mechanism would be relatively
>safe. However, in such circumstances, what would be the point of using
>it? Statically declared arrays should always use a manifest constant
>for their dimension so you will know the size. Please give me an
>example of a piece of code where the mechanism is actually useful rather
>than being a paliative for those who insist on salting their code with
>magic numbers.
how about
const char* msgs[] = {
"message1",
"message2",
...
"messageN"};
Sometimes the size of the array is not the fundamental property, but the list of
contents are.
--
richard_damon@iname.com (Redirector to my current best Mailbox)
rdamon@beltronicsInspection.com (Work Adddress)
Richad_Damon@msn.com (Just for Fun)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/15 Raw View
In article <6tm11t$56j$1@nnrp1.dejanews.com>, jkanze@otelo.ibmmail.com
writes
>I do. Compare the following two bits of code:
> static int const lengthX = 7 ;
> static int const x[ lengthX ] =
> {
> 1 , 1 , 2 , 3 , 5 , 8
> } ;
>and
> static int const x[] =
> {
> 1 , 1 , 2 , 3 , 5 , 8
> } ;
> static int const lengthX = sizeof( x ) / sizeof( x[ 0 ] ) ;
>One, of course, is wrong.
Oh! Which one? Yes I know lengthX evaluates to 6 in the second case
but the array has seven elements in the first, it is just that the last
one is 0.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/09/16 Raw View
Francis Glassborow wrote:
> In article <6tm11t$56j$1@nnrp1.dejanews.com>, jkanze@otelo.ibmmail.com
> writes
> >I do. Compare the following two bits of code:
> > static int const lengthX = 7 ;
> > static int const x[ lengthX ] =
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
> >and
> > static int const x[] =
> > {
> > 1 , 1 , 2 , 3 , 5 , 8
> > } ;
> > static int const lengthX = sizeof( x ) / sizeof( x[ 0 ] ) ;
> >One, of course, is wrong.
> Oh! Which one? Yes I know lengthX evaluates to 6 in the second case
> but the array has seven elements in the first, it is just that the last
> one is 0.
Which is often, though not necessarily, not what was intended. I use the
first syntax when I want the default values filled in (and insert an
appropriate comment, of course). I use the second syntax when I want the
provided values to determine the length.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/09/16 Raw View
In article <$+U6DGAonN$1Ewgc@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>
> In article <35FC56E7.15FB@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >For exactly the same reason, and in exactly the same sense, sizeof()
> >doesn't work on them either. However, I consider that to be an
> >inappropriate definition of 'work'. It does exactly what I would expect
> >it to do on array parameters, which is why I would never use it on them.
>
> But it also fails for dynamic arrays. If you never use globals and
> always keep your functions to one page the mechanism would be relatively
> safe. However, in such circumstances, what would be the point of using
> it? Statically declared arrays should always use a manifest constant
> for their dimension so you will know the size.
In 90% or more of the cases in my code, static arrays have a size calculated
by the compiler, according to the number of initializers. Now that the
standard contains vector, this percentage increases to 100%, since the
only time I use a C style array is because I need the static initialization.
Declaring an array size with a manifest constant is an exceptional case
in my code.
> Please give me an
> example of a piece of code where the mechanism is actually useful rather
> than being a paliative for those who insist on salting their code with
> magic numbers.
Three quick examples from actual code:
Parsing a printf type format specifier:
static ParserFnc const
parseFncTable[] =
{
&GB_Format_Impl::parseFlags ,
&GB_Format_Impl::parseWidth ,
&GB_Format_Impl::parsePrecision ,
&GB_Format_Impl::parseSpecifier ,
} ;
for ( int i = 0 ; ! isError() && i < GB_lengthOf( parseFncTable ) ; ++ i )
p = (this->*(parseFncTable[ i ]))( p ) ;
Validating a date string:
static int (*const charTypeTest[])( int ch ) =
{
isdigit , isdigit , ispunct ,
isdigit , isdigit , ispunct ,
isdigit , isdigit , isdigit , isdigit ,
} ;
if ( dateString.length() != GB_lengthOf( charTypeTest ) )
argumentError( "Error in date format" ) ;
else
{
for ( unsigned i = 0 ; i < GB_lengthOf( charTypeTest ) ; ++ i )
{
if ( ! (*charTypeTest[ i ])(
GB_static_cast( unsigned char , dateString[ i ] ) ) )
argumentError( "Error in date format" ) ;
}
}
Mapping a return status:
static int const table[] =
{
GB_EXIT_SUCCESS ,
GB_EXIT_WARNING ,
GB_EXIT_ERROR ,
GB_EXIT_FATAL ,
GB_EXIT_INTERNAL ,
} ;
GB_internal( (unsigned)( myMaximumGravitySeen ) < GB_lengthOf( table ) ) ;
return table[ myMaximumGravitySeen ] ;
Would you really suggest using a manifest constant to declare any
of these tables?
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/16 Raw View
In article <6tm0n5$4kg$1@nnrp1.dejanews.com>, jkanze@otelo.ibmmail.com
writes
>In 90% or more of the cases in my code, static arrays have a size calculated
>by the compiler, according to the number of initializers. Now that the
>standard contains vector, this percentage increases to 100%, since the
>only time I use a C style array is because I need the static initialization.
>Declaring an array size with a manifest constant is an exceptional case
>in my code.
>
OK. How about this for a guideline:
sizeof(array)/sizeof(element) shall only be used to determine the number
of elements in an array immediately after the declaration. For example:
int array[]={1, 2, 3, 5, 7, 11, 13};
int const array_size = sizeof(array)/sizeof(int);
What has always worried me is that the technique gets grabbed by
inexperienced programmers and used for such things as evaluating the
argument of a function like:
char buffer[100];
fgets(buffer, sizeof(buffer)/sizeof(char), stdin);
Of course you would be careful about any such usage, but we need to be
very defensive in the examples we hand to less experienced programmers.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: comeau@panix.com (Greg Comeau)
Date: 1998/09/12 Raw View
In article <35DC60CA.794B@wizard.net> James Kuyper <kuyper@wizard.net> writes:
>
>AllanW@my-dejanews.com wrote:
>...
>> out an array dimension. How many of us have written 10 or more
>> programs in a row without using this construct:
>> (sizeof(x)/sizeof(x[0]))
>
>I'd like to know why this has never been made a standard macro.
A few (briefly stated) reasons, including, but not limited to:
* It's easy to do yourself (of course, it's easy to be provided too)
* The C committee was mainly codifying existing practice
(often of implementations, rather than of programmers/code).
* The C++ committee was inventive, but more on issues of techniques and
programming styles. In one light on "more important issues". Oddly,
some of those things (templates, classes, STL, etc) can be used in
alternatives for the construct.
* It does not work on all arrays (for instance, array parameters).
* Weak?: for some, say with multi-dimensional array, it will probably be
invoked incorrectly often, or with dynamically allocated arrays too.
* Even at the "C level", in the grand scheme of things, the above is not
the only candidate construct possible. For instance, it can be debated
that a standard macro which computes the address of the last element
(or one past the last element) is more valuable, or that positional sentinal
values can sometimes be more important than sizes. And so on for other
such pathology.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C/C++ 4.2.38 -- New Release!
Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
***WEB: http://www.comeaucomputing.com***
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/09/13 Raw View
Greg Comeau wrote:
>
> In article <35DC60CA.794B@wizard.net> James Kuyper <kuyper@wizard.net> writes:
> >
> >AllanW@my-dejanews.com wrote:
> >...
> >> out an array dimension. How many of us have written 10 or more
> >> programs in a row without using this construct:
> >> (sizeof(x)/sizeof(x[0]))
> >
> >I'd like to know why this has never been made a standard macro.
>
> A few (briefly stated) reasons, including, but not limited to:
> * It's easy to do yourself (of course, it's easy to be provided too)
> * The C committee was mainly codifying existing practice
> (often of implementations, rather than of programmers/code).
The standard itself contains this construct as a example of how to use
sizeof().
> * The C++ committee was inventive, but more on issues of techniques and
> programming styles. In one light on "more important issues". Oddly,
> some of those things (templates, classes, STL, etc) can be used in
> alternatives for the construct.
I agree, the standard containers do reduce the need for such a
construct. However, C had been in existence for more than a decade
before the standard containers were standardized. I'm really surprised
that in all that time the construct was never standardized.
> * It does not work on all arrays (for instance, array parameters).
For exactly the same reason, and in exactly the same sense, sizeof()
doesn't work on them either. However, I consider that to be an
inappropriate definition of 'work'. It does exactly what I would expect
it to do on array parameters, which is why I would never use it on them.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/14 Raw View
In article <35FC56E7.15FB@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>For exactly the same reason, and in exactly the same sense, sizeof()
>doesn't work on them either. However, I consider that to be an
>inappropriate definition of 'work'. It does exactly what I would expect
>it to do on array parameters, which is why I would never use it on them.
But it also fails for dynamic arrays. If you never use globals and
always keep your functions to one page the mechanism would be relatively
safe. However, in such circumstances, what would be the point of using
it? Statically declared arrays should always use a manifest constant
for their dimension so you will know the size. Please give me an
example of a piece of code where the mechanism is actually useful rather
than being a paliative for those who insist on salting their code with
magic numbers.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/14 Raw View
In article <$+U6DGAonN$1Ewgc@robinton.demon.co.uk>,
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
> Please give me an
> example of a piece of code where the mechanism is actually useful rather
> than being a paliative for those who insist on salting their code with
> magic numbers.
As for the "Magic Numbers" concept: I don't see a huge amount of
difference between
#define NAME_LENGTH 24 // or extern const int NAME_LENGTH = 24;
char name[NAME_LENGTH]
and
char name[24];
#define NAME_LENGTH sizeof(name)/sizeof(name[0])
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: herbs@cntc.com (Herb Sutter)
Date: 1998/08/30 Raw View
>Vlad Harchev wrote:
>> ** Iterators are designed to substitute pointers
No. "Iterators are pointers" is not true (in general). It's exactly the
reverse: "Pointers are iterators" over arrays.
That is, the standard containers and iterators were deliberately
designed so that arrays are (work as) containers which can be iterated
over using pointers as random-access iterators.
Herb
---
Herb Sutter (mailto:herbs@cntc.com)
Current Network Technologies Corp 2695 North Sheridan Way, Suite 150
www.cntc.com www.peerdirect.com Mississauga Ontario Canada L5K 2N6
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/08/31 Raw View
In article <6rg377$4pi$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com
writes
>In fact, I'd go a step further away from this idea than anyone else
>I've heard yet: I would teach STL containers in the beginning C++
>classes, and save C-like arrays for the "advanced" classes!
>(The sole exception to this rule would be to teach beginning
>students that the type of "Hello" isn't basic_string<char>, but
>char* -- and tell them they'll find out why much, much later.)
I don't think you are alone in advocating that beginning C++ would be
better presented by avoiding arrays. Indeed I regularly do so when
presenting C++ training
>HOWEVER, I do think it's annoying to have to contort in order to find
>out an array dimension. How many of us have written 10 or more
>programs in a row without using this construct:
> (sizeof(x)/sizeof(x[0]))
>Not that this is particularly error-prone, but it's wordy and ugly.
It is deeply error prone because it assumes that x is the name of a
static (CS meaning not keyword) array and not a pointer to a dynamic or
a remote array.
>This is one of the few macros that I use on a regular basis, and
>I'd much rather see it as part of the language. But again, this
>would be used only with C-style arrays, so maybe it's not worth it
>now.
I would never advocate use of such a macro to anyone who did not have a
very good understanding of the relationship between arrays and pointers
(and that eliminates all novices as well as most authors:)
--
Francis Glassborow
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/09/02 Raw View
Francis Glassborow wrote:
>
> In article <6rg377$4pi$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com
> writes
...
> >HOWEVER, I do think it's annoying to have to contort in order to find
> >out an array dimension. How many of us have written 10 or more
> >programs in a row without using this construct:
> > (sizeof(x)/sizeof(x[0]))
> >Not that this is particularly error-prone, but it's wordy and ugly.
>
> It is deeply error prone because it assumes that x is the name of a
> static (CS meaning not keyword) array and not a pointer to a dynamic or
> a remote array.
I'm unfamiliar with the term 'remote', as used in this context.
...
> I would never advocate use of such a macro to anyone who did not have a
> very good understanding of the relationship between arrays and pointers
> (and that eliminates all novices as well as most authors:)
Someone without enough understanding to realize when the macro shouldn't
be used, shouldn't be allowed to work unsupervised on code where it
would be applicable. There are two many other equally dangerous related
mistakes they could also make.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/02 Raw View
In article <35EAB75E.794B@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>I'm unfamiliar with the term 'remote', as used in this context.
Accessed through a pointer (usually passed through one or more levels of
function calls)
--
Francis Glassborow
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Michel Michaud" <micm19@removethis.mail2.cstjean.qc.ca>
Date: 1998/09/02 Raw View
I posted the following 5 days ago, got lost probably...
[ moderator's note: I never saw it. -sdc ]
>In fact, I'd go a step further away from this idea than anyone else
>I've heard yet: I would teach STL containers in the beginning C++
>classes, and save C-like arrays for the "advanced" classes!
>(The sole exception to this rule would be to teach beginning
>students that the type of "Hello" isn't basic_string<char>, but
>char* -- and tell them they'll find out why much, much later.)
I am a teacher and tried that. Doesn't work. Very soon, you have
to explain that there are two kinds of array/vector. One by
one special cases fell on me, needing more explanation that I was
ready to give because I had used vector to simplify thing, not
to take more time to get to the same place.
The standard library is fine for people who already know programming.
But it does not make it easier to teach beginners about C++. Some
years ago I abandonned C as the first language without any trouble.
But trying to use vector everywhere did not work (I wrote two books
for beginners, I explain vector in the second one now, in the first
I used C array, but I do use string in the first... most of the time).
I think nobody, in the stadardization committee, cared about the learning
curve. If so, we would have file.open(a_string_type_variable) and so
many other things...
Michel Michaud micm19@removethis.mail2.cstjean.qc.ca
http://www3.sympatico.ca/michel.michaud
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: haberg@matematik.su.se (Hans Aberg)
Date: 1998/09/03 Raw View
In article <FW4H1.1936$lR.7900729@news21.bellglobal.com>, "Michel Michaud"
<micm19@removethis.mail2.cstjean.qc.ca> wrote:
>The standard library is fine for people who already know programming.
>But it does not make it easier to teach beginners about C++.
People start to use Java as first programming language, one can then
proceed to C++ I gather.
Otherwise, STL is great because it is simple and is in line with the
paradigm of C with half-open intervals.
But (returning to the original question) before STL was available, I
wrote linear lists which classified iterators as "uninitialized",
"before", "first", "last", "after", and "outdated". (STL begin()
corresponds to "first", and STL end() corresponds to "after".)
In addition, these could be dynamical, automatically moving to the next
insertion points: So iterators have colors for insertions "at", "before",
or "after", plus a direction "forward", "backward", or "static". These
were accessed via manipulator functions. So one could change the
characteristics of an iterator of a list to make it behave as a stack for
example.
So one can write quite complicated iterator models. I did it just in
order to investigate the semantics of the phenomenon.
Then one can write such more complicated models on top of the STL lists,
which I did in order to transition from my lists to STL. So now I use STL.
But the technique could be used to built more conatiner models on top of
STL.
Hans Aberg * Anti-spam: Remove "REMOVE." from email address.
* Email: Hans Aberg <haberg@REMOVE.member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: BourezC <BourezC@Assurnet.be>
Date: 1998/08/27 Raw View
Vlad Harchev wrote:
>
> Without 'null' feature, you have 3 ways -
> 1 to hack the iterator of the container
> 2 to add the special bit field or any other object to store
> the 'state' of the node.
> 3 To introduce 1 additional item in the container - with the
> logic - if 'left' or 'right' points to it, then the node
> has no left or right node. This implies that the reference
> to container shoudl be stored somewhere.
>
> Any of them aren't elegant as the use of 'null'.
I disagree with your quick conclusions. Point 3 is an elegant solution
too. It depends of your way of programming. But let me know how you
will define these unique conceptual 'null' iterator since iterators
are of different types, depending the containers. (For example, I
think about vector<bool> for wich the iterator is often implemented
as a class and vector<int> for which it is often define like int*).
Now you can define your 'null' iterator in the scope of your tree_node
structure for implementing it.
The same concept has been introduced with the vector class, with the
'past-the-end' value of the iterator. The only assumption you can make
about the 'past-the-end' value is what STL tells you about it. Here
each of container returns its own 'past-the-end' value.
Christophe Bourez
Assurnet
Belgium
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Vlad Harchev" <vladhar@imimail.ssau.ru>
Date: 1998/08/27 Raw View
>
>Vlad Harchev wrote:
>>
>> Without 'null' feature, you have 3 ways -
>> 1 to hack the iterator of the container
>> 2 to add the special bit field or any other object to store
>> the 'state' of the node.
>> 3 To introduce 1 additional item in the container - with the
>> logic - if 'left' or 'right' points to it, then the node
>> has no left or right node. This implies that the reference
>> to container shoudl be stored somewhere.
>>
>> Any of them aren't elegant as the use of 'null'.
>
>I disagree with your quick conclusions. Point 3 is an elegant solution
>too. It depends of your way of programming. But let me know how you
>will define these unique conceptual 'null' iterator since iterators
>are of different types, depending the containers. (For example, I
>think about vector<bool> for wich the iterator is often implemented
>as a class and vector<int> for which it is often define like int*)
being 'null' iterator - is a state of the iterator - each iterator
impelmentation decides how it will mark itself as being 'null'. The
indetifier
'null' is only the name of the element of the enumeration of type
'null_type'. For a given iterator 'i', you should think about the expression
(i==null) as a predicate, which is true, if the iterator i is in null
condition. Similary, the expression 'i=null' means only setting the iterator
'i' in the null condition, and after that action 'i==null' will be true.
Given two iterators 'i' and 'j' of different types,
the folloing code:
i=null; j=null; // set both to null iterator state
(i==j);
most possibly will be ill-formed since the even the iterators are both in
null state, the comparation operator for these two types can be not
declared. So, you should think of the null iterator 'i' as of plain iterator
'i' in special state - in null state. Iterators in null state should obey
the folloing rule, similar to the rule ofr C pointers: NO iterator in 'null'
state can be valid. As for C pointers, you then can assign valid value to
the iterator and use it.
The proposed concept is preferable, since it allows textually the same
expressions for dealing with C-pointers and iterators.
** Iterators are designed to substitute pointers - why don't they have
feature of pointers - NULL pointers.**
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1998/08/27 Raw View
Vlad Harchev wrote:
>
> >
>
> The proposed concept is preferable, since it allows textually the same
> expressions for dealing with C-pointers and iterators.
>
> ** Iterators are designed to substitute pointers - why don't they have
> feature of pointers - NULL pointers.**
Iterators are not designed to replace pointers. They are designed to
have some of the characteristics of pointers, and to be used to specify
ranges of values. Pointers are more powerful and more dangerous. We
don't need to impose on iterators the dangers that pointers carry with
them.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/22 Raw View
On 22 Aug 1998 16:53:46 GMT, Matt Arnold <mXaXrXnXoXlXd@mXoXtXu.cXoXm> wrote:
>BTW, is there a way to write sizeof_array() as a template? I haven't found
>it.
sizeof_array(...) wouldn't be an integral constant as it's a function
call.
sizeof(sizer(...)) is an integral constant -- that is, a constant
required to be known at compile time, and the same across all
architectures (that's why float values can't be integral constants).
char const (&sizer(T (&)[N]))[N]; // declaration
char const (&sizer(T (&)[N]))[N] { abort(); } // definition
The definition is just to deter us from calling the function.
Note: in sizeof(...), the ... is not evaluated.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/08/22 Raw View
In article <35DE01F2.23AE5943@acm.org>,
Pete Becker <petebecker@acm.org> wrote:
>
> James Kuyper wrote:
> >
> > AllanW@my-dejanews.com wrote:
> > ...
> > > out an array dimension. How many of us have written 10 or more
> > > programs in a row without using this construct:
> > > (sizeof(x)/sizeof(x[0]))
> >
> > I'd like to know why this has never been made a standard macro.
> >
>
> Because it's usually wrong:
>
> void f(char c[])
> {
> printf("%lu\n", (unsigned long)(sizeof(c)/sizeof(c[0])));
> }
>
> int main()
> {
> char a[10];
> char b[20];
> f(a);
> f(b);
> return 0;
> }
And if we made it a standard macro, say asize() (the name I use most
often, because array_size is too awkward), we would have
void f(char c[])
{
printf("%lu\n", (unsigned long)asize(c));
}
which is no more or less correct than the original. It is, however,
a bit more readable -- and perhaps it's easier for maintenance
programmers to realize the mistake?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1998/08/22 Raw View
Matt Arnold wrote:
> Pete Becker wrote in message <35DE01F2.23AE5943@acm.org>...
> >James Kuyper wrote:
> >>
> >> AllanW@my-dejanews.com wrote:
> >> ...
> >> > out an array dimension. How many of us have written 10 or more
> >> > programs in a row without using this construct:
> >> > (sizeof(x)/sizeof(x[0]))
> >> I'd like to know why this has never been made a standard macro.
> >Because it's usually wrong:
> [snip code examples of (sizeof(x)/sizeof(x[0])) getting bad values]
> I guess what James is really asking is, "Why isn't there *some* standard way
> to get the size of an array (in elements, not bytes) in C and C++?". Why
> are we all still writing our own SIZEOF_ARRAY macros?
> I'm not suggesting one be added, but certainly an official sizeof_array()
> operator could be made safe to use (not letting one fall into the traps
> illustrated by Pete's examples).
Template or not, the name of an array decays into a pointner to its
first element in almost all cases. Once that has happened, there's no
way to get the size information without passing additional information
around. Once you do that you no longer have a C-style array, and you may
as well call it std::vector.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1998/08/22 Raw View
In article <6rl78u$n4r$1@news.harvard.net>,
mXaXrXnXoXlXd@mXoXtXu.cXoXm says...
[ ... ]
> I guess what James is really asking is, "Why isn't there *some* standard way
> to get the size of an array (in elements, not bytes) in C and C++?". Why
> are we all still writing our own SIZEOF_ARRAY macros?
I think at least in C++, it has been added to, e.g. class vector<>,
which is nearly always preferable to using a built-in array in any
case.
--
Later,
Jerry.
The Universe is a figment of its own imagination.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Greg Colvin" <spam@me.not>
Date: 1998/08/23 Raw View
Siemel Naran wrote:
> ...
> char const (&sizer(T (&)[N]))[N]; // declaration
And I said to myself: "Look Ma, no macros!"
So, if you don't need an integral constant, you can do:
template<typename T,const size_t N> size_t size(T(&)[N]) { return N; }
And, for completeness:
template<typename T,const size_t N> T* begin(T(&a)[N]) { return &a[0]; }
template<typename T,const size_t N> T* end(T(&a)[N]) { return &a[N]; }
And, for when you need an integral constant:
template<typename T,const size_t N> char const (&sizer(T (&)[N]))[N] {
unexpected(); }
Perhaps these belong in the standard library?
And, yes, I compiled (Intel C++, EDG front end) and successfully ran a
test:
main() {
int A[10];
cout << size(A) << endl;
cout << end(A) - begin(A) << endl;
cout << sizeof(sizer(A)) << endl;
}
Greg Colvin
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/24 Raw View
Siemel Naran wrote in message ...
>
>On 22 Aug 1998 16:53:46 GMT, Matt Arnold <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
wrote:
>
>>BTW, is there a way to write sizeof_array() as a template? I haven't
found
>>it.
>
>sizeof_array(...) wouldn't be an integral constant as it's a function
>call.
>
>sizeof(sizer(...)) is an integral constant -- that is, a constant
>required to be known at compile time, and the same across all
>architectures (that's why float values can't be integral constants).
>
>char const (&sizer(T (&)[N]))[N]; // declaration
>char const (&sizer(T (&)[N]))[N] { abort(); } // definition
[snip]
I assume that was intended to be a template?
template <class T, const size_t N>
char const (&sizer(T (&)[N]))[N];
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the X's from Reply-To: to obtain my valid e-mail address.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/24 Raw View
Jerry Coffin wrote in message ...
>
>In article <6rl78u$n4r$1@news.harvard.net>,
>mXaXrXnXoXlXd@mXoXtXu.cXoXm says...
>
>[ ... ]
>
>> I guess what James is really asking is, "Why isn't there *some* standard
way
>> to get the size of an array (in elements, not bytes) in C and C++?". Why
>> are we all still writing our own SIZEOF_ARRAY macros?
>
>I think at least in C++, it has been added to, e.g. class vector<>,
>which is nearly always preferable to using a built-in array in any
>case.
Yes, but it's hard to use std::vector for a static data table, isn't it?
However, I suppose that nice "c_array" STL container wrapper/adaptor would
obviate the need for a "sizeof_array" macro/template/operator, etc..
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the X's from Reply-To: to obtain my valid e-mail address.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/24 Raw View
Greg Colvin wrote in message <01bdce44$5e80cfc0$3e4a5ed1@gcolvin-hpc>...
>
>Siemel Naran wrote:
[snip]
>And, for when you need an integral constant:
>
> template<typename T,const size_t N> char const (&sizer(T (&)[N]))[N] {
>unexpected(); }
[snip]
>And, yes, I compiled (Intel C++, EDG front end) and successfully ran a
>test:
Fooey! I tested with my compiler, Borland C++ 5.02, and it doesn't like it.
Are there any workarounds or alternative approaches for things like "sizer"?
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the X's from Reply-To: to obtain my valid e-mail address.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/08/24 Raw View
Pete Becker wrote:
>
> James Kuyper wrote:
> >
> > AllanW@my-dejanews.com wrote:
> > ...
> > > out an array dimension. How many of us have written 10 or more
> > > programs in a row without using this construct:
> > > (sizeof(x)/sizeof(x[0]))
> >
> > I'd like to know why this has never been made a standard macro.
> >
>
> Because it's usually wrong:
I #define an ELEMENTS() macro in a lot of my code, and I guarantee you
that it gives the intended result in every context where I use it.
> void f(char c[])
> {
> printf("%lu\n", (unsigned long)(sizeof(c)/sizeof(c[0])));
The above would of course not be one of those contexts.
> }
>
> int main()
> {
> char a[10];
> char b[20];
> f(a);
> f(b);
> return 0;
> }
What do you mean that it's wrong? It should print a value of 1 for both
invocations of f(), which is the correct value. Of course, this is
probably not the intended value, but every construct can be misused, no
matter how intrinsically useful it is. If such a macro were part of the
standard, its description would have to explain the limits on its
usefulness, just like any other feature of the language.
I'll grant you that the availability of standard containers with a
size() member reduces the need for this macro; I've used it mostly in C
code.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/08/24 Raw View
In article <6rl78u$n4r$1@news.harvard.net>,
"Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm> wrote:
>
> Pete Becker wrote in message <35DE01F2.23AE5943@acm.org>...
> >
> >James Kuyper wrote:
> >>
> >> AllanW@my-dejanews.com wrote:
> >> ...
> >> > out an array dimension. How many of us have written 10 or more
> >> > programs in a row without using this construct:
> >> > (sizeof(x)/sizeof(x[0]))
> >>
> >> I'd like to know why this has never been made a standard macro.
> >>
> >
> >Because it's usually wrong:
>
> [snip code examples of (sizeof(x)/sizeof(x[0])) getting bad values]
>
> I guess what James is really asking is, "Why isn't there *some* standard way
> to get the size of an array (in elements, not bytes) in C and C++?". Why
> are we all still writing our own SIZEOF_ARRAY macros?
>
> I'm not suggesting one be added, but certainly an official sizeof_array()
> operator could be made safe to use (not letting one fall into the traps
> illustrated by Pete's examples).
The common array_size/asize/sizeof_array macros can never avoid this
trap, because they can't tell the difference between an array name and
a pointer. But the compiler can. If sizeof_array was a keyword, it
would be illegal to use except on arrays. Then Mr. Becker's examples
wouldn't give bad values, because they would be syntax errors.
> BTW, is there a way to write sizeof_array() as a template? I haven't found
> it.
I don't think so. If anyone's figured this out, I'd like to know about
it; we could override it for pointer types.
> Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
> any and all unsolicited commercial e-mail sent to this address is
> subject to a download and archival fee in the amount of $500 US.
> E-mailing this address denotes acceptance of these terms.
Does this work? Have you managed to collect $500 from anyone?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/24 Raw View
AllanW@my-dejanews.com wrote in message <6rsdr8$fuo$1@nnrp1.dejanews.com>...
>
>In article <6rl78u$n4r$1@news.harvard.net>,
> "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm> wrote:
[snip]
>> I'm not suggesting one be added, but certainly an official sizeof_array()
>> operator could be made safe to use (not letting one fall into the traps
>> illustrated by Pete's examples).
>
>The common array_size/asize/sizeof_array macros can never avoid this
>trap, because they can't tell the difference between an array name and
>a pointer. But the compiler can. If sizeof_array was a keyword, it
>would be illegal to use except on arrays. Then Mr. Becker's examples
>wouldn't give bad values, because they would be syntax errors.
>
>> BTW, is there a way to write sizeof_array() as a template? I haven't
found
>> it.
>
>I don't think so. If anyone's figured this out, I'd like to know about
>it;
Well, apparently you can do this (this is taken from other posts in this
thread, so don't take this idea as mine -- I just regurgitating it)...
template <typename T, const size_t N>
char const (& sizer(T (const &)[N])[N] { terminate(); }
In case it's hard to see, that's template function named sizer() that
returns a const reference to a char array that's the same size as the T
array passed to it. (I'm not sure if that second "const" is in the right
place.)
Anyway, you use sizer() like this...
Foo foo_array[100]
size_t foo_size = sizeof(sizer(foo_array)); // magic!
>we could override it for pointer types.
Do to what? Produce a compliation error? Ah, yes...
template <typename T>
void sizer(T*) { terminate(); }
Because it returns "void", this version of sizer() can't be used with
sizeof() as in the valid sample code above. Hmmm, I just hope these
sizer()s can exist without causing ambiguity problems. I don't really know
because the first sizer() doesn't work with my compiler (Borland C++
5.02) -- drat!
BTW, the calls to terminate() are simply to discourage calling sizer()
directly. Using sizer() with sizeof() -- the only way it's intended --
doesn't cause it to be evaluated (called).
>> Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
>> any and all unsolicited commercial e-mail sent to this address is
[snip]
>
>Does this work?
Don't know. I'm just hoping spammers filter out Usenet postings containing
phrases like "US Code, Title 47, Chapter 5, Subchapter II, Sec. 227" and
"download and archival fee" to the same extent they filter them for valid
e-mail addresses. I saw this stuff on someone else's postings and thought
I'd try it.
>Have you managed to collect $500 from anyone?
No. :-)
[ moderator's note: Please, no further discussion of anti-spam
techniques. There are newsgroups devoted to that topic. -sdc ]
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the capital X's to e-mail me.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Vlad Harchev <vladhar@imimail.ssau.ru>
Date: 1998/08/17 Raw View
Possible extension to standart:
A lot of algorithms that store iterators in some containers or objects
require the special meaning for some iterator. For C-pointers, it was the
NULL pointer. Unfortunately, there is no such ability for iterators, and the
writers of templized algorithms have to use different hacks to achive such
functionality. Here is a proposal on implementation of such functionality.
Since the operators for enums can be overloaded, and the pointer can be
initialized | compared by|with the constant expression that evaluates to zero, the
apporoach is to define the special enumaration type with one enumerator in it
- with the value zero named 'null'. Having done so, it's quite straightforward
to implement the support for 'null' functionality for iterators - all
iterators contain some pointer or reference to the stored object.
Also, each
container may define the member function that will return the 'null' iterator.
Such function shall have the signature 'null_type null() const' .
[For example:
enum null_type { null };//the key enumeration
// now some iterator:
struct foo_iterator
{
....
foo_iterator(null_type ) { /*make some stored pointer zero. */}
bool operator==(null_type);//compare the pointer with zero.
bool operator!=(null_type);
....
};
//some container
struct foo_container
{
...
null_type null() const;
...
}
void foo()
{ // for conforming compiler, the following should be ok
char* str = null;
...
if (str==null) { ... };
};
-- end example]
Notes:
1) It's under question, whether each operator shoudl define
'bool operator!() const' - the luxury thing that make the iterators and
pointers indistinguishable.
2) Some compilers doesn't allow overlaoding on enums, and some do not allow
constant expressions with null value to be used for initialization,
comparation with pointers (for example GCC 2.7.2).
3) IMHO, this simple extension has particular importance and should be considered
by STL writers.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ark@research.att.com (Andrew Koenig)
Date: 1998/08/17 Raw View
In article <35D80D92.304C7BE8@imimail.ssau.ru>,
Vlad Harchev <vladhar@imimail.ssau.ru> wrote:
> Possible extension to standart:
> A lot of algorithms that store iterators in some containers or objects
> require the special meaning for some iterator. For C-pointers, it was the
> NULL pointer. Unfortunately, there is no such ability for iterators, and the
> writers of templized algorithms have to use different hacks to achive such
> functionality. Here is a proposal on implementation of such functionality.
> Since the operators for enums can be overloaded, and the pointer can be
> initialized | compared by|with the constant expression that evaluates to zero, the
> apporoach is to define the special enumaration type with one enumerator in it
> - with the value zero named 'null'. Having done so, it's quite straightforward
> to implement the support for 'null' functionality for iterators - all
> iterators contain some pointer or reference to the stored object.
It is less simple than you may think, for two reasons:
1. Should a null iterator be required to be distinct from any other
iterator? If not, it is hard to see what good it is. If so, what
would you do about a singly-linked list class that uses 0 for an
off-the-end iterator?
2. This suggestion is not an extension, because it would make some programs
illegal that are presently legal. Those programs are precisely those
that define iterators that do not support a null value.
--
--Andrew Koenig
ark@research.att.com
http://www.research.att.com/info/ark
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: icedancer.zamboni@ibm.zamboni.net (Ken Walter)
Date: 1998/08/18 Raw View
On Mon, 17 Aug 1998 16:50:30, Vlad Harchev <vladhar@imimail.ssau.ru>
wrote:
On a container with two "ends" (depending on which direction you are
iterating)
there could be three different values to NULL.
One for each end and the never been used before zero.
This would require testing for all three each time in some cases.
Ken Walter
Remove .zamboni to reply
All the above is hearsay and the opinion of no one in particular
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/08/18 Raw View
Andrew Koenig wrote:
> In article <35D80D92.304C7BE8@imimail.ssau.ru>,
> Vlad Harchev <vladhar@imimail.ssau.ru> wrote:
> > Possible extension to standart:
> > A lot of algorithms that store iterators in some containers or objects
> > require the special meaning for some iterator. For C-pointers, it was the
> > NULL pointer. Unfortunately, there is no such ability for iterators, and the
> > writers of templized algorithms have to use different hacks to achive such
> > functionality. Here is a proposal on implementation of such functionality.
> > Since the operators for enums can be overloaded, and the pointer can be
> > initialized | compared by|with the constant expression that evaluates to zero, the
> > apporoach is to define the special enumaration type with one enumerator in it
> > - with the value zero named 'null'. Having done so, it's quite straightforward
> > to implement the support for 'null' functionality for iterators - all
> > iterators contain some pointer or reference to the stored object.
> It is less simple than you may think, for two reasons:
> 1. Should a null iterator be required to be distinct from any other
> iterator? If not, it is hard to see what good it is. If so, what
> would you do about a singly-linked list class that uses 0 for an
> off-the-end iterator?
>
> 2. This suggestion is not an extension, because it would make some programs
> illegal that are presently legal. Those programs are precisely those
> that define iterators that do not support a null value.
Both problems could be avoided by defining a new iterator category,
say nullable iterator. Pointers would be nullable, and current iterators
would generally not be nullable. No current code would break, since no
current code requires or expects nullable iterators. Especially the
containers which don't provide nullable iterators would not break,
since nullable iterators are not demanded - they are an option, just
like random access iterators are not demanded.
BTW, a question to the singly-linked-list-iterator mentioned above:
If the end iterator is defined as NULL, then you get
slist1.end()==slist2.end(). Is this allowed by the standard?
(Or, to be more precise, would that iterator class still be considered
a valid forward iterator class according to the standard?)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ark@research.att.com (Andrew Koenig)
Date: 1998/08/18 Raw View
In article <35D94CB1.89B1E171@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> Both problems could be avoided by defining a new iterator category,
> say nullable iterator. Pointers would be nullable, and current iterators
> would generally not be nullable. No current code would break, since no
> current code requires or expects nullable iterators. Especially the
> containers which don't provide nullable iterators would not break,
> since nullable iterators are not demanded - they are an option, just
> like random access iterators are not demanded.
Indeed. But no library container offers nullable iterators and no library
algorithm requires them. So, imagine for a moment that we could still
add such an iterator category to the standard. What effect would it have
on any standard-conforming program or implementation?
> BTW, a question to the singly-linked-list-iterator mentioned above:
> If the end iterator is defined as NULL, then you get
> slist1.end()==slist2.end(). Is this allowed by the standard?
> (Or, to be more precise, would that iterator class still be considered
> a valid forward iterator class according to the standard?)
Interesting question. For a definitive ruling, I would have to check the
words very carefully, but pragmatically speaking, whether a type is a particular
kind of iterator depends only on its behavior over the set of values with
which it is used. In general, the only contexts in which it would matter
that slist1.end()==slist2.end() might be possible are contexts in which,
if it were not possible, the ultimate result would be undefined.
--
--Andrew Koenig
ark@research.att.com
http://www.research.att.com/info/ark
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: abell8920@mindspring.com (Andrew Bell)
Date: 1998/08/19 Raw View
On 18 Aug 1998 16:33:47 GMT, Christopher Eltschka
<celtschk@physik.tu-muenchen.de> wrote:
>BTW, a question to the singly-linked-list-iterator mentioned above:
>If the end iterator is defined as NULL, then you get
>slist1.end()==slist2.end(). Is this allowed by the standard?
Note that this situation happens already for empty vectors (at least
using the SGI implementation); .begin() == .end() == NULL.
Andrew Bell
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/08/19 Raw View
Christopher Eltschka wrote:
>
> BTW, a question to the singly-linked-list-iterator mentioned above:
> If the end iterator is defined as NULL, then you get
> slist1.end()==slist2.end(). Is this allowed by the standard?
> (Or, to be more precise, would that iterator class still be considered
> a valid forward iterator class according to the standard?)
Stream iterators use an arbitrary constant (created by the iterator's
default constructor) to represent the end of an input sequence. It has
no relation to any particular stream, but is merely recognized by
operator== as a symbol for "end of input". Although this iterator isn't
produced by end() on some container, the fact that such identical
objects can be used to represent the ends of different sequences would
suggest that the same could be done with actual containers.
--
Ciao,
Paul
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/19 Raw View
How about an extension to make builtin arrays more like STL containers. So
give them functions size(), begin(), and end()? This is just a notational
convenience.
int a[10];
a.begin(); // same as &a[0]
a.end(); // same as &a[10]
a.size(); // same as 10
We do have
const char (&sizer(const T (&)[N]))[N] { abort(); }
sizeof(sizer(a)); // same as 10
It is slick, but still a little ugly.
Furthermore, sizeof(...) is an integral constant even though it looks looks
like a function call. So a.size() is an integral constant too.
But now, int[10]::iterator is the same as int*.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/08/19 Raw View
sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>How about an extension to make builtin arrays more like STL containers. So
>give them functions size(), begin(), and end()? This is just a notational
>convenience.
There have been several proposals over the years to make builtin
arrays look more like classes, have value semantics, and so on.
By the time we get to a fully fleshed-out proposal, the suggestion
breaks a lot of existing code, leads to ambiguities (syntactical
or semantic), is overly complex, or doesn't solve enough of the
problem to be truly useful. Often a proposal has all four flaws.
The conclusion has always been to leave builtin arrays alone
(while wishing C had different rules for arrays) and recommend
using a class for arrays when you want class features. For
example, the standard library now has vector and valarray,
and you can roll your own if you don't like either of those.
I'm not dismissing this suggestion, just providing some background.
The next step would be to make a complete proposal along the
lines of what is discussed in D&E. People can then throw
rocks or roses at it.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/08/20 Raw View
In article <slrn6tma5e.gs6.sbnaran@fermi.ceg.uiuc.edu>,
sbnaran@KILL.uiuc.edu wrote:
>
> How about an extension to make builtin arrays more like STL containers. So
> give them functions size(), begin(), and end()? This is just a notational
> convenience.
>
> int a[10];
> a.begin(); // same as &a[0]
> a.end(); // same as &a[10]
> a.size(); // same as 10
>
> We do have
>
> const char (&sizer(const T (&)[N]))[N] { abort(); }
> sizeof(sizer(a)); // same as 10
>
> It is slick, but still a little ugly.
>
> Furthermore, sizeof(...) is an integral constant even though it looks looks
> like a function call. So a.size() is an integral constant too.
>
> But now, int[10]::iterator is the same as int*.
For this to be meaningful, begin/end/size would have to be keywords. This
changes
vector::iterator vector::begin()
into
vector::iterator vector::operator begin()
which breaks the STL itself, if nothing else.
At some level, we want to reassure ourselves that most of the C++
library can be written in C++. (If only to reassure ourselves that
the implementors have had experience with C++ :-) I think that it's
good to separate the "low-level" concepts like C-type arrays from
the "high-level" concepts like containers.
In fact, I'd go a step further away from this idea than anyone else
I've heard yet: I would teach STL containers in the beginning C++
classes, and save C-like arrays for the "advanced" classes!
(The sole exception to this rule would be to teach beginning
students that the type of "Hello" isn't basic_string<char>, but
char* -- and tell them they'll find out why much, much later.)
HOWEVER, I do think it's annoying to have to contort in order to find
out an array dimension. How many of us have written 10 or more
programs in a row without using this construct:
(sizeof(x)/sizeof(x[0]))
Not that this is particularly error-prone, but it's wordy and ugly.
This is one of the few macros that I use on a regular basis, and
I'd much rather see it as part of the language. But again, this
would be used only with C-style arrays, so maybe it's not worth it
now.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Vlad Harchev <vladhar@imimail.ssau.ru>
Date: 1998/08/20 Raw View
Ken Walter wrote:
> On Mon, 17 Aug 1998 16:50:30, Vlad Harchev <vladhar@imimail.ssau.ru>
> wrote:
>
> On a container with two "ends" (depending on which direction you are
> iterating)
> there could be three different values to NULL.
> One for each end and the never been used before zero.
> This would require testing for all three each time in some cases.
>
> Ken Walter
>
0 A lot of people understood me literally - as if the iterator is 'null', than it should
have the pointer initialized with NULL. They implied, that such extension will break
any existing code. Why the binary '1' can't be used as a mark for 'null' iterator ?
1 It seems to me, that the number of special NULL values that can be stored in each
iterator makes no difference.
The special value that the 'null' iterator will hold for such container can be binary
'3' - it will be as invalid pointer value as 0 on most systems.And for such container,
the value to test by the 'operator=(null_type)' is only one - what ever the container
uses for indicating the special iterator (eg '3'). Even if the impelementation allows
the address with the integral value > 0 (eg 1,2,3), the special object can be introduced
(of any type), for example named 'pseudo_zero_address_object', then member
'operator=(null_type)' has to check the stored pointer in the iterator with the address
of that object - it's one instruction only. So, adding extra NULL value doesn't
influences any other method of container and iterator in non-debug mode.
2 Moreover, the null iterators should have the semantics of the NULL pointer in C -
it's allowed to dereference them, but
the result will be undefined. This implies that methods of containers in non-debug mode
shouldn't check the passed iterator
values for being null iterators - it's the user responsibility.
3 Of course, user can introduce special template (for example to as Valentin Bonnard
suggested) but this requires extra
bytes in each class. On the other end, the iterator has the ability to store the
special value in it's pointer without growing.
So, the idea was to use the ability to store some extra information in the iterator -
and not to grow the stored objects.
4 Input and Output iterators shouldn't be compared with 'null' and set to 'null'. The
reasons are obvious.
5 The standart algorithms in non-debug mode shouldn't neither use nor check null
iterators.
6 With the respect of writen above, it seems to me that such exstension doesn't break
any existing code and fits well
in C paradigms of pointers and STL concept for containers.
Here is an example of the simple structure that makes obvious use of the 'null'
iterators.
template <class T>
struct tree_node
{
typedef tree_node self;
typedef some_container<self> iterator;
iterator parent;
iterator right, // ==null if no right node
left; // ==null if no left node
T data;
//other code goes here
};
In C, it's quite obvious use of NULL. It's also obvious and elegant to use the paradigm
of NULL - 'null' in the C++.
If the tree does allow removal of elements, then the only valid container that allows
the semantics of tree will be some
sort of list. If the tree doesn't allow removal of elements, then the container can be
deque. This implies, that the 'null' support it useful for all containers.
Without 'null' feature, you have 3 ways -
1 to hack the iterator of the container
2 to add the special bit field or any other object to store the 'state' of the
node.
3 To introduce 1 additional item in the container - with the logic - if 'left' or
'right' points to it, then the node has no
left or right node. This implies that the reference to container shoudl be stored
somewhere.
Any of them aren't elegant as the use of 'null'.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/08/20 Raw View
In article <35D94CB1.89B1E171@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> BTW, a question to the singly-linked-list-iterator mentioned above:
> If the end iterator is defined as NULL, then you get
> slist1.end()==slist2.end(). Is this allowed by the standard?
> (Or, to be more precise, would that iterator class still be considered
> a valid forward iterator class according to the standard?)
Why? What in the standard would suggest that comparing iterators
to two unrelated sequences is defined? I would expect undefined behavior.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/08/20 Raw View
AllanW@my-dejanews.com wrote:
...
> out an array dimension. How many of us have written 10 or more
> programs in a row without using this construct:
> (sizeof(x)/sizeof(x[0]))
I'd like to know why this has never been made a standard macro.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Greg Colvin" <spam@me.not>
Date: 1998/08/20 Raw View
Siemel Naran writes:
> How about an extension to make builtin arrays more like STL containers.
So
> give them functions size(), begin(), and end()? This is just a
notational
> convenience.
>
> int a[10];
> a.begin(); // same as &a[0]
> a.end(); // same as &a[10]
> a.size(); // same as 10
Or, with no extension, you could have:
int a[10];
begin(a); // same as &a[0]
end(a); // same as &a[10]
size(a); // same as 10
Greg Colvin
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/20 Raw View
On 20 Aug 1998 21:28:04 GMT, Greg Colvin <spam@me.not> wrote:
>Or, with no extension, you could have:
>
> int a[10];
> begin(a); // same as &a[0]
> end(a); // same as &a[10]
> size(a); // same as 10
No, this won't work because the results are no longer integral constants.
int a[10];
double [size(a)]; // error: VLA not allowed!
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/20 Raw View
On 20 Aug 1998 15:59:35 GMT, AllanW@my-dejanews.com
>For this to be meaningful, begin/end/size would have to be keywords. This
No. When you call operator[] on a builtin array, the compiler
calls the builtin operator[]. When you call operator[] on a
user class, the compiler calls the user operator[] of the class.
Same thing with these begin/end/size functions. If the object to
which this function is applied is a builtin array, then do the
builtin begin/end/size function. Otherwise, do the builtin
function.
Also, the following should be an error:
int a[10];
&a.begin; // pointer to member not allowed on builtin arrays
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/20 Raw View
On 19 Aug 1998 21:09:56 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>>How about an extension to make builtin arrays more like STL containers. So
>>give them functions size(), begin(), and end()? This is just a notational
>>convenience.
>There have been several proposals over the years to make builtin
>arrays look more like classes, have value semantics, and so on.
>
>By the time we get to a fully fleshed-out proposal, the suggestion
>breaks a lot of existing code, leads to ambiguities (syntactical
>or semantic), is overly complex, or doesn't solve enough of the
>problem to be truly useful. Often a proposal has all four flaws.
Please give me an example of where this could go wrong. Since
you've seen these proposals, I'm sure you can enlighten me.
The syntax above does not lead to ambiguities.
vector<int> v(10);
v[3]; // calls vector's operator[]
v.size(); // calls vector's size()
int v[10];
v[3]; // calls builtin operator[]
v.size(); // 'calls' builtin size()
It won't break old code. The old ways still work.
It is simple.
You do have one point: it is not very useful.
We often use builtin arrays for tables known at compile time. Like
a table of all the keywords that the compiler supports, or a table
of the months of the year, etc. These tables are fixed at compile
time, and so they should be a little more efficient. We just want
to make the syntax for dealing with these tables a little easier
and less error prone.
>I'm not dismissing this suggestion, just providing some background.
>The next step would be to make a complete proposal along the
>lines of what is discussed in D&E. People can then throw
>rocks or roses at it.
What is D&E?
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/08/21 Raw View
sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>On 19 Aug 1998 21:09:56 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>>sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>>>How about an extension to make builtin arrays more like STL containers. So
>>>give them functions size(), begin(), and end()? This is just a notational
>>>convenience.
>>There have been several proposals over the years to make builtin
>>arrays look more like classes, have value semantics, and so on.
>>
>>By the time we get to a fully fleshed-out proposal, the suggestion
>>breaks a lot of existing code, leads to ambiguities (syntactical
>>or semantic), is overly complex, or doesn't solve enough of the
>>problem to be truly useful. Often a proposal has all four flaws.
>Please give me an example of where this could go wrong. Since
>you've seen these proposals, I'm sure you can enlighten me.
>The syntax above does not lead to ambiguities.
It does create new inconsistencies. Size, begin, and end are
not built-in operators and they are not keywords. They can be
ordinary user-defined identifiers, yet they would have a special
meaning in certain syntactical constructs, unrelated to scope.
I don't believe anything else in C++ fits that description.
Something could be said for adding something like Ada's
"attributes", with a special syntax. Example:
x`size
x`begin
x`end
That wouldn't look so ad-hoc. It would be a general mechanism,
not something cobbled up just to use one kind of data type in
one kind of operation. I don't remember seeing a serious proposal
to add attributes to C++.
>We often use builtin arrays for tables known at compile time.
> ... We just want
>to make the syntax for dealing with these tables a little easier
>and less error prone.
Use a map or vector or other standard data type that has the
properties you want, or write your own class.
>What is D&E?
As explained in the FAQ for this newsgroup (question B9), D&E is
the book "The Design and Evolution of C++", by Bjarne Stroustrup.
It gives the background and reasons for why C++ is the way it is.
It also contains examples of proposals that were not accepted, and
gives guidelines for preparing proposals that would have a chance
of being accepted.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/08/21 Raw View
Steve Clamage <stephen.clamage@sun.com> writes:
> Something could be said for adding something like Ada's
> "attributes", with a special syntax. Example:
> x`size
> x`begin
> x`end
> That wouldn't look so ad-hoc. It would be a general mechanism,
> not something cobbled up just to use one kind of data type in
> one kind of operation. I don't remember seeing a serious proposal
> to add attributes to C++.
numerical_limits is a better replacement of attributes.
And it requires no language extension.
Some attributes aren't covered by numerical_limits, but
writing trait classes is easy.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/21 Raw View
Siemel Naran wrote in message ...
>
>On 19 Aug 1998 21:09:56 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>>sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>
>>>How about an extension to make builtin arrays more like STL containers.
So
>>>give them functions size(), begin(), and end()? This is just a
notational
>>>convenience.
Why do we need a language extention to do this? (see below)
[snip]
>We often use builtin arrays for tables known at compile time. Like
>a table of all the keywords that the compiler supports, or a table
>of the months of the year, etc. These tables are fixed at compile
>time, and so they should be a little more efficient. We just want
>to make the syntax for dealing with these tables a little easier
>and less error prone.
Why doesn't someone just create a nice adapter template the can be used to
"wrap" any instance of any type of built-in array and make it appear like
any other STL-compliant container? Wouldn't this be just (or at least
almost) as conventient as having built-in arrays be STL-compliant themselves
via weird language extensions?
Here's a sketch to show what I mean...
// Create a table at compile-time.
Foo t[] = { /* initializers */ };
// Adapt and use it at run-time as a full-fledged
// container.
builtin_array_adapter<Foo> a(t, sizeof(t));
for (builtin_array_adapter<Foo> iter = a.begin();
iter != a.end(); ++iter)
.
.
// etc.
>>I'm not dismissing this suggestion, just providing some background.
>>The next step would be to make a complete proposal along the
>>lines of what is discussed in D&E. People can then throw
>>rocks or roses at it.
>
>What is D&E?
It's shorthand for the book entitled "The Design and Evolution of C++" by
Bjarne Stroustrup.
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the X's from Reply-To: to obtain my valid e-mail address.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/21 Raw View
On 21 Aug 1998 00:12:44 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>It does create new inconsistencies. Size, begin, and end are
>not built-in operators and they are not keywords. They can be
>ordinary user-defined identifiers, yet they would have a special
>meaning in certain syntactical constructs, unrelated to scope.
>I don't believe anything else in C++ fits that description.
Well, operator[] behaves differently when applied to builtin and
user types.
builtin_array[0]; // calls builtin array
myclass_array[0]; // calls myspace::MyClass::operator[](int)
Similarly, size() will behave differently depending on which type it
is applied to.
builtin_array.size(); // calls sizeof(sizer(builtin_array))
myclass_array.size(); // calls myspace::MyClass::begin()
So size() is used as an operator in the context of builtin arrays,
and as a function in all other contexts. But operators are
functions. So size() is always used as a function.
>Use a map or vector or other standard data type that has the
>properties you want, or write your own class.
Fine, but I'd like everything to be fixed at compile time to
avoid run-time overhead.
Please give me an example program or two illustrating the ambiguity
that could arise.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/08/21 Raw View
sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>On 21 Aug 1998 00:12:44 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>>It does create new inconsistencies. Size, begin, and end are
>>not built-in operators and they are not keywords. They can be
>>ordinary user-defined identifiers, yet they would have a special
>>meaning in certain syntactical constructs, unrelated to scope.
>>I don't believe anything else in C++ fits that description.
>Well, operator[] behaves differently when applied to builtin and
>user types.
Please read what you quoted above.
The [] is built into the language, and "operator" is a C++ keyword.
You are proposing to treat ordinary user-defineable identifiers as
having a special meaning independent of scope. I'm stressing scope,
because you can define, e.g., "begin" as a method of a class,
and depending on scope, it will be interpreted that way. Apart
from that scope, it might some other meaning, or no meaning.
>Please give me an example program or two illustrating the ambiguity
>that could arise.
Please read what I wrote initially. I never said your suggestion
would lead to ambiguities.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/08/21 Raw View
In article <6rijga$2v2$1@news.harvard.net>,
Matt Arnold <mXaXrXnXoXlXd@mXoXtXu.cXoXm> wrote:
[Deleted]
>Why doesn't someone just create a nice adapter template the can be used to
>"wrap" any instance of any type of built-in array and make it appear like
>any other STL-compliant container? Wouldn't this be just (or at least
>almost) as conventient as having built-in arrays be STL-compliant themselves
>via weird language extensions?
>
>Here's a sketch to show what I mean...
>
>
> // Create a table at compile-time.
>
> Foo t[] = { /* initializers */ };
>
>
> // Adapt and use it at run-time as a full-fledged
> // container.
>
> builtin_array_adapter<Foo> a(t, sizeof(t));
>
> for (builtin_array_adapter<Foo> iter = a.begin();
> iter != a.end(); ++iter)
> .
> .
>
> // etc.
See chapter 17.5.4. in B.Stroustrup "C++ Programming Language" 3rd ed,
for another way of doing it (more a wrapper than adapter):
template <class T,int max> struct c_array {
...
typedef T* iterator;
...
T v[max];
iterator begin() {return v;}
iterator end() {return v+max;}
};
And used as:
c_array<int,10> a={1,2,3,4,5,6,7,8,9,10};
for(c_array<int,10>::iterator i=a.begin();i!=a.end();++i) ...
instead of
Foo t[]={...}
builtin_array_adapter<Foo> a(t,sizeof(t));
Note that c_array does not have any constructors and v is not
private. That is an important part of the design, since a c-like
structure can be initialized by a list of values, exactly as a
c-like array.
This is not mentioned in the text, but you have to figure it out for yourself.
Adding reverse_iterator, checked indexing as 'at' etc to Stroustrup's class
is left as an excersice for the reader.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1998/08/21 Raw View
James Kuyper wrote:
>
> AllanW@my-dejanews.com wrote:
> ...
> > out an array dimension. How many of us have written 10 or more
> > programs in a row without using this construct:
> > (sizeof(x)/sizeof(x[0]))
>
> I'd like to know why this has never been made a standard macro.
>
Because it's usually wrong:
void f(char c[])
{
printf("%lu\n", (unsigned long)(sizeof(c)/sizeof(c[0])));
}
int main()
{
char a[10];
char b[20];
f(a);
f(b);
return 0;
}
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Matt Arnold" <mXaXrXnXoXlXd@mXoXtXu.cXoXm>
Date: 1998/08/22 Raw View
Pete Becker wrote in message <35DE01F2.23AE5943@acm.org>...
>
>James Kuyper wrote:
>>
>> AllanW@my-dejanews.com wrote:
>> ...
>> > out an array dimension. How many of us have written 10 or more
>> > programs in a row without using this construct:
>> > (sizeof(x)/sizeof(x[0]))
>>
>> I'd like to know why this has never been made a standard macro.
>>
>
>Because it's usually wrong:
[snip code examples of (sizeof(x)/sizeof(x[0])) getting bad values]
I guess what James is really asking is, "Why isn't there *some* standard way
to get the size of an array (in elements, not bytes) in C and C++?". Why
are we all still writing our own SIZEOF_ARRAY macros?
I'm not suggesting one be added, but certainly an official sizeof_array()
operator could be made safe to use (not letting one fall into the traps
illustrated by Pete's examples).
BTW, is there a way to write sizeof_array() as a template? I haven't found
it.
Regards,
Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com
Remove all the X's from Reply-To: to obtain my valid e-mail address.
---------
Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227,
any and all unsolicited commercial e-mail sent to this address is
subject to a download and archival fee in the amount of $500 US.
E-mailing this address denotes acceptance of these terms.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]