Topic: Simpler Constant Initialization in Classes
Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/12/09 Raw View
On 06 Dec 97 05:49:06 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com>
wrote:
>Steve Clamage wrote:
>>
>> Unless you change the fundamental meaning of "size of a type" or of
>> the sizeof operator, IMHO it doesn't make sense to overload sizeof. If
>> you allow overloading of sizeof, you would still need a reliable way
>> to express the static size of a type or object.
>
>Well, actually I agree. But the standard already allows overloading things like
>the comma operator, which I consider a bit de trop.
C++ originally did not allow overloading the comma operator.
Stroustrup says he finally yielded to requests to overload comma, but
that was before the C++ Committee was formed. By then it was a fait
accompli.
---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/12/10 Raw View
Fergus Henderson wrote:
[...]
> Note however that a simple shell script such as the above would
> not constitute a conforming implementation; a conforming implementation
> must also include documentation of all implementation-defined features,
> such as "what constitutes a diagnostic".
>
> >> The problem arise because the compiler can emit spurious
> >> diagnostics (well, perhaps it has been fixed in Morritstown,
> >> I haven't checked).
> >
> >How can this be fixed without making a lot of useful warnings
> >illegal?
>
> Easily. For example, require conforming implementations to (provide a
> mode in which they) reject, i.e. refuse to translate, any program for
> which a diagnostic is required. With this addition, conforming implementations
> would be required to accept certain programs (as they are currently)
> and also to reject certain programs. It could still be implementation-defined
> how to tell whether the implementation has accepted or rejected a program,
> but because it would be possible to test which of these has occurred,
> then trivial shell scripts such as the above would no longer be conforming.
> A conforming implementation would at least have to contain code to check
> whether programs are ill-formed.
An idea which came to my mind now:
What if the diagnostic output is just the output of the source itself?
No one can doubt that from the source itself you can determine if it
is ill-formed.
The documentation would then be:
"Rejection of a program is indicated by output of ill-formed C++ source
to stderr. Acception of a program is indicated by output of well-formed
C++ source to stderr."
Wow, this compiler would even reject all the code where no diagnostics
is
required! :-)
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/30 Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
|> Christopher Eltschka wrote:
|> >
|> > Valentin Bonnard wrote:
|> > >
|> > > And integral expressions _must_ be computed at compile time,
|> > > so the compiler must have an evaluator for + - * / % & | ^
|> > > << >> ?: (perhaps I have missed an operator)
|> >
|> > Really must? Or is it just that the current implementations need
|> > to do so?
|>
|> I can think of a few places where the compiler absolutely must perform integer
|> arithmetic.
|>
|> 1) The preprocessor understands arithmetic, and can do conditional compilation
|> based on its result:
|>
|> #define FOO 1
|> #define BAR 2
|> ...
|> #if FOO + BAR > 10
|> ...
|> #endif
Note, however, that the arithmetic in the preprocessor does not have to
conform to that in the runtime. (It may use more bits, and I think that
it may also use less bits, although I'm not sure.) So this is not
necessarily "evaluating an integral expression" in the same sense as it
would be elsewhere.
|> 2) A template may have a constant parameter. In order to determine type
|> equivalence, the compiler must reduce it to a single number:
|>
|> template <int x> class foo {};
|>
|> extern void f(foo<2>&);
|> extern void f(foo<4>&);
|>
|> void test() {
|> f(foo<1+1>()); // must call f(foo<2>&);
|> f(foo<2+2>()); // must call f(foo<4>&);
|> }
|>
|> 3) In some cases, an array size _must_ be computed at compile time. For
|> instance, a PODS must be compatible with C, so any array within a PODS cannot
|> be handled in some cute indirect way by the compiler, as it could theoretically
|> be if it wasn't a PODS:
|>
|> #define MAXLEN 100
|>
|> struct foo { int x[MAXLEN + 1]; } the_foo;
|>
|> extern "C" f(foo*);
|>
|> f(&the_foo);
I'm not sure about this one. The rules for PODS's are slightly
different in C and C++. In particular, C++ always uses name
equivalence, whereas C has a concept of "compatible declarations", and
in practice, uses structural equivalence between compilation units.
With name equivalence, I'm not sure where the compiler would need to
know the length of the array. (With structural equivalence, of course,
it would have to know whether two lengths were the same in order to know
whether two structures were in fact the same type.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/30 Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
|> John Potter wrote:
|> >
|> > Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
|> >
|> > : IMHO there's nothing in the standard stating that *anything* is
|> > : calculated at compile time.
|> >
|> > How about
|> > int const size 5;
|> > char data[size];
|>
|> He'd argue that that could be compiled into a global location
|> containing the number 5, plus code to call operator new to create
|> the array and store the resulting pointer into a variable, as long
|> as the compiler was smart enough to translate all references to
|> "data" so that that pointer is fetched.
In fact, except for the global location, this is more or less what
happens anyway, at least with auto variables. Normally, all auto
variables are allocated at once, using the compile time constant
expression which is the sum of the sizeof of all local variables.
There is, however, nothing (except quality of implementation) to prevent
the compiler from storing all of the lengths in global variables, and
doing the addition at run-time. With a bit of imagination, I think that
one could find a similar solution for static variables. In practice,
compile time constant folding is one of the simplest optimizations
imaginable, and so no one bothers trying to invent alternatives to avoid
it.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/12/02 Raw View
Paul D. DeRocco wrote:
>
> Christopher Eltschka wrote:
> >
> > Valentin Bonnard wrote:
> > >
> > > And integral expressions _must_ be computed at compile time,
> > > so the compiler must have an evaluator for + - * / % & | ^
> > > << >> ?: (perhaps I have missed an operator)
> >
> > Really must? Or is it just that the current implementations need
> > to do so?
>
> I can think of a few places where the compiler absolutely must perform integer
> arithmetic.
>
> 1) The preprocessor understands arithmetic, and can do conditional compilation
> based on its result:
>
> #define FOO 1
> #define BAR 2
> ...
> #if FOO + BAR > 10
> ...
> #endif
>
Well, the compiler could try to compile both ways (emitting a warning if
one of
them fails), and then produce run time code to decide which version to
execute
(or to fail if the erroneous one is the correct one).
> 2) A template may have a constant parameter. In order to determine type
> equivalence, the compiler must reduce it to a single number:
>
> template <int x> class foo {};
>
> extern void f(foo<2>&);
> extern void f(foo<4>&);
>
> void test() {
> f(foo<1+1>()); // must call f(foo<2>&);
> f(foo<2+2>()); // must call f(foo<4>&);
> }
>
The compiler could emit a warning "Function call may be illegal" and
then
emit the following code:
void test()
{
switch(1+1)
{
case 2: f<foo<2> >(); break;
case 4: f<foo<4> >(); break;
default: cerr << "Illegal function call" << endl; abort();
}
}
> 3) In some cases, an array size _must_ be computed at compile time. For
> instance, a PODS must be compatible with C, so any array within a PODS cannot
> be handled in some cute indirect way by the compiler, as it could theoretically
> be if it wasn't a PODS:
>
> #define MAXLEN 100
>
> struct foo { int x[MAXLEN + 1]; } the_foo;
>
> extern "C" f(foo*);
>
> f(&the_foo);
Well, who tells you *which* C compiler it must interface with? Why not
one
that was written for compile-tinm?
BTW, the compiler could code this as
void* the_foo_address;
__init()
{
the_foo_address=malloc((MAXLEN+1)*sizeof(int)+__int_padding(MAXLEN+1));
}
extern "C" f(foo*);
f((foo*)the_foo_a);
and calculate all the expressions at runtime.
Note that I don't say I want the compiler to do that - it's just that
it is possible. Indeed I guess no compiler writer will ever do such
contortions
to avoid compile time integer calculations...
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/12/02 Raw View
In <34801FF2.AF955EEF@ix.netcom.com>
"Paul D. DeRocco" <pderocco@ix.netcom.com> wrote:
>
> John Potter wrote:
> >
> > Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> >
> > : IMHO there's nothing in the standard stating that *anything* is
> > : calculated at compile time.
> >
> > How about
> > int const size 5;
> > char data[size];
>
> He'd argue that that could be compiled into a global location containing the
> number 5, plus code to call operator new to create the array and store the
> resulting pointer into a variable, as long as the compiler was smart enough to
> translate all references to "data" so that that pointer is fetched.
Perhaps. But below is a constant expression which the compiler *must* evaluate
at compile time:
static int array[1+sizeof(int)/100-1];
This results in the definition of an array of zero elements, which must
result in a compile-time diagnostic. (I believe it's called a "constraint
violation".)
-- david.tribble@noSPAM.central.beasys.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Gabor Greif" <gabor@datawatch.de>
Date: 1997/12/02 Raw View
On Tue, Dec 2, 1997 10:52 AM, Christopher Eltschka
<mailto:celtschk@physik.tu-muenchen.de> wrote:
>The compiler could emit a warning "Function call may be illegal" and
>then emit the following code:
>
>void test()
>{
> switch(1+1)
> {
> case 2: f<foo<2> >(); break;
> case 4: f<foo<4> >(); break;
> default: cerr << "Illegal function call" << endl; abort();
> }
>}
I know that the above is only of academic/theoretical interest, but do you
know the phrase "combinatorical explosion"? :-)
Gabor
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/12/02 Raw View
J. Kanze wrote:
>
> "Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>
> |> 3) In some cases, an array size _must_ be computed at compile time.
> |> For instance, a PODS must be compatible with C, so any array within
> |> a PODS cannot be handled in some cute indirect way by the compiler,
> |> as it could theoretically be if it wasn't a PODS:
> |>
> |> #define MAXLEN 100
> |>
> |> struct foo { int x[MAXLEN + 1]; } the_foo;
> |>
> |> extern "C" f(foo*);
> |>
> |> f(&the_foo);
>
> I'm not sure about this one. The rules for PODS's are slightly
> different in C and C++. In particular, C++ always uses name
> equivalence, whereas C has a concept of "compatible declarations", and
> in practice, uses structural equivalence between compilation units.
> With name equivalence, I'm not sure where the compiler would need to
> know the length of the array. (With structural equivalence, of course,
> it would have to know whether two lengths were the same in order to know
> whether two structures were in fact the same type.)
Whoever started this thread theorized that static and auto array sizes
wouldn't _really_ be needed at compile time, because an implementation
could conceivably use operator new[] at runtime to create these, as
long as it hid this fact from the programmer. That is, given the above
struct, it could really be implemented as:
struct foo { auto_ptr<int> x; } the_foo;
as long as the compiler faked sizeof(the_foo.x) appropriately, etc.
My point is that such shenanigans would be prohibited if C compatibility
was desired, because one might pass such a structure to a C function
that assumed the more conventional layout. In order to provide the
conventional layout, the array size would have to be computed at
compile time, regardless of whether C used name equivalence or
structural equivalence.
By the way, it just occurred to me that it might be useful to be able to
overload sizeof. Was that ever discussed?
--
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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/12/02 Raw View
Christopher Eltschka wrote:
>
> Paul D. DeRocco wrote:
> >
> > Christopher Eltschka wrote:
> > >
> > > Valentin Bonnard wrote:
> > > >
> > > > And integral expressions _must_ be computed at compile time,
> > > > so the compiler must have an evaluator for + - * / % & | ^
> > > > << >> ?: (perhaps I have missed an operator)
and == != < > <= >= ~
> > > Really must? Or is it just that the current implementations need
> > > to do so?
> >
> > I can think of a few places where the compiler absolutely must
> > perform integer arithmetic.
Me too.
> The compiler could emit a warning "Function call may be
> illegal" and then emit the following code:
Only because the current wording of the std is badly broken.
When it'll be fixed, your compiler won't be conformant
anymore (that is, when spurious diagnostic will be
forbiden).
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/12/04 Raw View
On 02 Dec 97 16:16:46 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com>
wrote:
>By the way, it just occurred to me that it might be useful to be able to
>overload sizeof. Was that ever discussed?
C++ uses static type definition. The size of an object (except for
dynamic arrays, where sizeof is not allowed) is the size of its type.
The size is the number of bytes needed by objects of the type, and may
include padding at the end. The sizeof operator applies to compile
time and reports that size.
Unless you change the fundamental meaning of "size of a type" or of
the sizeof operator, IMHO it doesn't make sense to overload sizeof. If
you allow overloading of sizeof, you would still need a reliable way
to express the static size of a type or object.
Maybe you could make a case for introducing a runtime overloadable
operator to report some other notion of size. But of course you can
already do that by writing your own functions.
---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/12/05 Raw View
J. Kanze <kanze@gabi-soft.fr> writes:
> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> |> > IMHO there's nothing in the standard stating that *anything* is
> |> > calculated at compile time.
You are wrong.
> |> > If you had a computer that executed C++ source directly, copy would
> |> > be a conforming compiler :-)
> |>
> |> Sorry, that's wrong. But
> |>
> |> echo Diagnostic: Your program may contains errors
> |> cp $1 $2
> |>
> |> would be (the compiler must emit a diagnostic).
>
> Except that the standard doesn't mention compiler anywhere. It talks
> about an implementation, and specifies that certain diagnostics must be
> emitted during translation. Translation includes everything except
> execution, including the linker.
I didn't wrote 'compiler'. I mean that this is a conforming
implementation. But:
echo Sorry, ressource limits exceeded
+ appropriate documentation
is a simplier one, and works for any target, which is way
more powerfull.
> (An interesting question: must translation fully take place before
> execution? What if loading a DLL reveals an undefined external?)
I hope so.
> |> The problem arise because the compiler can emit spurious
> |> diagnostics (well, perhaps it has been fixed in Morritstown,
> |> I haven't checked).
>
> I don't think that it can be fixed, really. We don't want to ban
> warnings, do we?
warnings aren't diagnostics (for the purpose of the fix)
> |> And integral expressions _must_ be computed at compile time,
> |> so the compiler must have an evaluator for + - * / % & | ^
> |> << >> ?: (perhaps I have missed an operator)
>
> Again, nothing need occur before link time. Even then, I'm not sure.
> The "compiler" does need the results of certain integral expressions for
> e.g. array dimensions, but I don't think that it is forbidden for the
> implementation to use some sort of dynamic allocation for all arrays.
I wrote compile time to mean translation time. Sorry. Perhaps
I should have written during or before link time.
And of course some arrays can be dynamically allocated; it's
terribly difficult to implement for all arrays, but possible
in theory:
struct T {
int first;
int array [complicated_integral_expression];
int last;
} x;
assert (&x.first < &x.array[0]);
assert (&x.array[complicated_expression-1] < &x.last);
It's silly to try to do that without another good reason,
as it doesn't avoid any compile time evaluation of integral
expression (the reason for that is left as an exercice to
the reader; hint: I assume the implementation is not broken).
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/12/06 Raw View
Steve Clamage wrote:
>
> Unless you change the fundamental meaning of "size of a type" or of
> the sizeof operator, IMHO it doesn't make sense to overload sizeof. If
> you allow overloading of sizeof, you would still need a reliable way
> to express the static size of a type or object.
Well, actually I agree. But the standard already allows overloading things like
the comma operator, which I consider a bit de trop. (In fact, I rather wish
they didn't allow || and && to be overloaded, since the built-in forms imply
useful sequence points.) I was just wondering if, in their zeal to allow an
orgy of overloading, the participants in the standards discussions ever kicked
it around.
--
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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/12/06 Raw View
Valentin Bonnard wrote:
>
> J. Kanze <kanze@gabi-soft.fr> writes:
>
> > Valentin Bonnard <bonnardv@pratique.fr> writes:
> >
> > |> > IMHO there's nothing in the standard stating that *anything* is
> > |> > calculated at compile time.
>
> You are wrong.
>
Proof?
> > |> > If you had a computer that executed C++ source directly, copy would
> > |> > be a conforming compiler :-)
> > |>
> > |> Sorry, that's wrong. But
> > |>
> > |> echo Diagnostic: Your program may contains errors
> > |> cp $1 $2
> > |>
> > |> would be (the compiler must emit a diagnostic).
> >
> > Except that the standard doesn't mention compiler anywhere. It talks
> > about an implementation, and specifies that certain diagnostics must be
> > emitted during translation. Translation includes everything except
> > execution, including the linker.
>
> I didn't wrote 'compiler'. I mean that this is a conforming
> implementation. But:
>
> echo Sorry, ressource limits exceeded
>
> + appropriate documentation
>
> is a simplier one, and works for any target, which is way
> more powerfull.
>
Sorry, but a lot of old home computers which started with an BASIC
interpreter only wouldn't have given the expected result...
But there *is* indeed a code that works on all known implementations:
GHJGHJGHUGJKGHNBGHUYOTFUBVNMBNMBNGYTYIUITYIUZZZZAZCFFGFHJGKJHJKKQ
togeter with the documentation: "Every message you might get means:
Resource limits exceeded."
> > (An interesting question: must translation fully take place before
> > execution? What if loading a DLL reveals an undefined external?)
>
> I hope so.
What exactly do you hope: That an implementation that supports dynamic
linking is nonconforming, because the user who runs the program might
have an outdated DLL (or even not have the DLL at all)? Or would you
add this to the resource limits of the program? ("Sorry, not enough
resources of type void f(double) in DLL whatever; 1 needed, 0 found"
:-))
But maybe just you hope that loading a DLL reveals an undefined
external... ;-)
>
> > |> The problem arise because the compiler can emit spurious
> > |> diagnostics (well, perhaps it has been fixed in Morritstown,
> > |> I haven't checked).
> >
> > I don't think that it can be fixed, really. We don't want to ban
> > warnings, do we?
>
> warnings aren't diagnostics (for the purpose of the fix)
>
That's IMHO not a good idea. It would make compilers that emit a warning
about nonstandard extensions nonconforming. They would have to refuse
to compile (which is not the purpose of extensions, of course).
> > |> And integral expressions _must_ be computed at compile time,
> > |> so the compiler must have an evaluator for + - * / % & | ^
> > |> << >> ?: (perhaps I have missed an operator)
> >
> > Again, nothing need occur before link time. Even then, I'm not sure.
> > The "compiler" does need the results of certain integral expressions for
> > e.g. array dimensions, but I don't think that it is forbidden for the
> > implementation to use some sort of dynamic allocation for all arrays.
>
> I wrote compile time to mean translation time. Sorry. Perhaps
> I should have written during or before link time.
>
> And of course some arrays can be dynamically allocated; it's
> terribly difficult to implement for all arrays, but possible
> in theory:
>
> struct T {
> int first;
> int array [complicated_integral_expression];
> int last;
> } x;
>
> assert (&x.first < &x.array[0]);
> assert (&x.array[complicated_expression-1] < &x.last);
>
> It's silly to try to do that without another good reason,
> as it doesn't avoid any compile time evaluation of integral
> expression (the reason for that is left as an exercice to
> the reader; hint: I assume the implementation is not broken).
Well the compiler could translate this to the following (assuming
pointers "are" ints):
size_t __T_size;
T* x;
__at_init()
{
__T_size=sizeof(int)+padding_int_int+(sizeof(int)*complicated_integral_expression)
+padding_int_int+sizeof(int)+padding_int_end;
// of course, padding_int_int is 0 - but adding 0 is
arithmetic ;-)
x=(T*)malloc(__T_size);
}
assert(int(x) < int(x)+sizeof(int)+padding_int_int+0*sizeof(int));
assert(int(x)+sizeof(int)+padding_int_int+(complicated_expression-1)*sizeof(int)
< int(x)+sizeof(x)+padding_int_int
+(complicated_integral_expression)*sizeof(int)+padding_int_int);
Now, where has the compiler evaluated the integral expressions?
(Or, if not, why is the implementation broken?)
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/12/06 Raw View
David R Tribble wrote:
>
> In <34801FF2.AF955EEF@ix.netcom.com>
> "Paul D. DeRocco" <pderocco@ix.netcom.com> wrote:
> >
> > John Potter wrote:
> > >
> > > Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> > >
> > > : IMHO there's nothing in the standard stating that *anything* is
> > > : calculated at compile time.
> > >
> > > How about
> > > int const size 5;
> > > char data[size];
> >
> > He'd argue that that could be compiled into a global location containing the
> > number 5, plus code to call operator new to create the array and store the
> > resulting pointer into a variable, as long as the compiler was smart enough to
> > translate all references to "data" so that that pointer is fetched.
>
> Perhaps. But below is a constant expression which the compiler *must* evaluate
> at compile time:
>
> static int array[1+sizeof(int)/100-1];
>
> This results in the definition of an array of zero elements, which must
> result in a compile-time diagnostic. (I believe it's called a "constraint
> violation".)
The compiler could emit a warning for _each_ array which involves an
expression. This would satisfy the need for a diagnostics in case of
error, and the need of proper compilation otherwise.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/27 Raw View
Darron Shaffer wrote:
[...]
> > There is no such as a floating point constant expression, so there
> > are no rules about it.
> >
>
> What I was suggesting was adding these, which would allow:
>
> class B
> {
> const float pi = 3.14159;
>
> ...
> };
>
> but not:
>
> class C
> {
> const float pi_over_4 = 3.14159 / 4;
>
> }
>
> Which preserves the current reluctance to force a vendor to emulate
> target machine floating point.
But the vendor isn't forced to emulate it. He can compile the
second thing to:
__init: (code called at beginning of program)
calculate 3.14159/4 and store it in C::pi_over_4
... (f.ex. constructor calls for global objects)
IMHO there's nothing in the standard stating that *anything* is
calculated at compile time.
If you had a computer that executed C++ source directly, copy would
be a conforming compiler :-)
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/27 Raw View
Christopher Eltschka wrote:
>
> Darron Shaffer wrote:
> > > There is no such as a floating point constant expression, so there
> > > are no rules about it.
Right
> > What I was suggesting was adding these, which would allow:
> > const float pi = 3.14159;
> > const float pi_over_4 = 3.14159 / 4;
> > Which preserves the current reluctance to force a vendor to emulate
> > target machine floating point.
>
> But the vendor isn't forced to emulate it. He can compile the
> second thing to:
>
> __init: (code called at beginning of program)
> calculate 3.14159/4 and store it in C::pi_over_4
> ... (f.ex. constructor calls for global objects)
Perfectly correct.
> IMHO there's nothing in the standard stating that *anything* is
> calculated at compile time.
>
> If you had a computer that executed C++ source directly, copy would
> be a conforming compiler :-)
Sorry, that's wrong. But
echo Diagnostic: Your program may contains errors
cp $1 $2
would be (the compiler must emit a diagnostic).
The problem arise because the compiler can emit spurious
diagnostics (well, perhaps it has been fixed in Morritstown,
I haven't checked).
And integral expressions _must_ be computed at compile time,
so the compiler must have an evaluator for + - * / % & | ^
<< >> ?: (perhaps I have missed an operator)
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1997/11/29 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
: IMHO there's nothing in the standard stating that *anything* is
: calculated at compile time.
How about
int const size 5;
char data[size];
?
John
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/29 Raw View
Valentin Bonnard wrote:
>
> Christopher Eltschka wrote:
> >
> > Darron Shaffer wrote:
>
> > > > There is no such as a floating point constant expression, so there
> > > > are no rules about it.
>
> Right
>
> > > What I was suggesting was adding these, which would allow:
>
> > > const float pi = 3.14159;
>
> > > const float pi_over_4 = 3.14159 / 4;
>
> > > Which preserves the current reluctance to force a vendor to emulate
> > > target machine floating point.
> >
> > But the vendor isn't forced to emulate it. He can compile the
> > second thing to:
> >
> > __init: (code called at beginning of program)
> > calculate 3.14159/4 and store it in C::pi_over_4
> > ... (f.ex. constructor calls for global objects)
>
> Perfectly correct.
>
> > IMHO there's nothing in the standard stating that *anything* is
> > calculated at compile time.
> >
> > If you had a computer that executed C++ source directly, copy would
> > be a conforming compiler :-)
>
> Sorry, that's wrong. But
>
> echo Diagnostic: Your program may contains errors
> cp $1 $2
>
> would be (the compiler must emit a diagnostic).
Does the standard say that a diagnostic must consist of a string
output to screen? You could view the return code of cp as diagnostic:
return code 0 means, the executable was created, but the code may contain
errors; return code !=0 means the file wasn't created for some reason.
Now, cp always gives a return code, so there always is a diagnostic ;-)
> The problem arise because the compiler can emit spurious
> diagnostics (well, perhaps it has been fixed in Morritstown,
> I haven't checked).
How can this be fixed without making a lot of useful warnings
illegal? For example, I'd not like the warning "conversion from float
to int" to be illegal. And forbidding warnings like "The OS function
you used here is obsolete" (I don't know if such warnings exist in real
compilers) would IMHO be not a good idea, as well.
I guess, to describe exactly what you may give as diagnostic would be
as complicated as defining the standard itself...
(Example: If a shareware compiler writes: "Warning: You are using an
unregistered version of this compiler. The License will expire in 3 days."
- is this a diagnostic? What if a (very clever) compiler tells you:
"Warning: You are linking GPLed code. The result will be GPLed
automatically.")
>
> And integral expressions _must_ be computed at compile time,
> so the compiler must have an evaluator for + - * / % & | ^
> << >> ?: (perhaps I have missed an operator)
Really must? Or is it just that the current implementations need
to do so? I can imagine an implementation that sets up all memory
at runtime with malloc calls, initializes all constants at runtime,
and mallocs automatic variables as well, freeing them at the end
of the block. This way, you'd have to know no value at compile time
(even the converting of digit strings to numbers could be done at
runtime; very ineffective, but possible) and therefore the compiler
wouldn't have to know anything.
BTW, who tells you the compile is finished when the compiler/linker
stop doing anything? What about a compiler that just adds the source
code to the executable of the real compiler, which then does all the
work at run time? (This would be the equivalent of the "cp compiler"
for machines not executing C++ code natively ;-))
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/29 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
>Valentin Bonnard wrote:
>>
>> Christopher Eltschka wrote:
>> >
>> > If you had a computer that executed C++ source directly, copy would
>> > be a conforming compiler :-)
>>
>> Sorry, that's wrong. But
>>
>> echo Diagnostic: Your program may contains errors
>> cp $1 $2
>>
>> would be (the compiler must emit a diagnostic).
>
>Does the standard say that a diagnostic must consist of a string
>output to screen?
No.
>You could view the return code of cp as diagnostic:
Yes, you could.
Note however that a simple shell script such as the above would
not constitute a conforming implementation; a conforming implementation
must also include documentation of all implementation-defined features,
such as "what constitutes a diagnostic".
>> The problem arise because the compiler can emit spurious
>> diagnostics (well, perhaps it has been fixed in Morritstown,
>> I haven't checked).
>
>How can this be fixed without making a lot of useful warnings
>illegal?
Easily. For example, require conforming implementations to (provide a
mode in which they) reject, i.e. refuse to translate, any program for
which a diagnostic is required. With this addition, conforming implementations
would be required to accept certain programs (as they are currently)
and also to reject certain programs. It could still be implementation-defined
how to tell whether the implementation has accepted or rejected a program,
but because it would be possible to test which of these has occurred,
then trivial shell scripts such as the above would no longer be conforming.
A conforming implementation would at least have to contain code to check
whether programs are ill-formed.
Actually there is still another loophole; even with the above change,
the shell script
#!/bin/sh
echo "Sorry, resource limit exceeded" 1>&2
exit 1
would still be conforming.
--
Fergus Henderson <fjh@cs.mu.oz.au> WWW: <http://www.cs.mu.oz.au/~fjh>
Note: due to some buggy software and a (probably accidental)
denial-of-service attack, any mail sent to me or comp.std.c++ between
Tue Nov 25 20:00:00 UTC (6am Wed, local time)
and Wed Nov 26 06:00:00 UTC (4pm, local time)
may have gone into the bit-bucket. Please re-send it.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/29 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
|> > IMHO there's nothing in the standard stating that *anything* is
|> > calculated at compile time.
|> >
|> > If you had a computer that executed C++ source directly, copy would
|> > be a conforming compiler :-)
|>
|> Sorry, that's wrong. But
|>
|> echo Diagnostic: Your program may contains errors
|> cp $1 $2
|>
|> would be (the compiler must emit a diagnostic).
Except that the standard doesn't mention compiler anywhere. It talks
about an implementation, and specifies that certain diagnostics must be
emitted during translation. Translation includes everything except
execution, including the linker.
(An interesting question: must translation fully take place before
execution? What if loading a DLL reveals an undefined external?)
|> The problem arise because the compiler can emit spurious
|> diagnostics (well, perhaps it has been fixed in Morritstown,
|> I haven't checked).
I don't think that it can be fixed, really. We don't want to ban
warnings, do we?
|> And integral expressions _must_ be computed at compile time,
|> so the compiler must have an evaluator for + - * / % & | ^
|> << >> ?: (perhaps I have missed an operator)
Again, nothing need occur before link time. Even then, I'm not sure.
The "compiler" does need the results of certain integral expressions for
e.g. array dimensions, but I don't think that it is forbidden for the
implementation to use some sort of dynamic allocation for all arrays.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/29 Raw View
Christopher Eltschka wrote:
>
> Valentin Bonnard wrote:
> >
> > And integral expressions _must_ be computed at compile time,
> > so the compiler must have an evaluator for + - * / % & | ^
> > << >> ?: (perhaps I have missed an operator)
>
> Really must? Or is it just that the current implementations need
> to do so?
I can think of a few places where the compiler absolutely must perform integer
arithmetic.
1) The preprocessor understands arithmetic, and can do conditional compilation
based on its result:
#define FOO 1
#define BAR 2
...
#if FOO + BAR > 10
...
#endif
2) A template may have a constant parameter. In order to determine type
equivalence, the compiler must reduce it to a single number:
template <int x> class foo {};
extern void f(foo<2>&);
extern void f(foo<4>&);
void test() {
f(foo<1+1>()); // must call f(foo<2>&);
f(foo<2+2>()); // must call f(foo<4>&);
}
3) In some cases, an array size _must_ be computed at compile time. For
instance, a PODS must be compatible with C, so any array within a PODS cannot
be handled in some cute indirect way by the compiler, as it could theoretically
be if it wasn't a PODS:
#define MAXLEN 100
struct foo { int x[MAXLEN + 1]; } the_foo;
extern "C" f(foo*);
f(&the_foo);
--
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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/29 Raw View
John Potter wrote:
>
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> : IMHO there's nothing in the standard stating that *anything* is
> : calculated at compile time.
>
> How about
> int const size 5;
> char data[size];
He'd argue that that could be compiled into a global location containing the
number 5, plus code to call operator new to create the array and store the
resulting pointer into a variable, as long as the compiler was smart enough to
translate all references to "data" so that that pointer is fetched.
--
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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/21 Raw View
Theodore Todorov <todorov@sbghp10.in2p3.fr> writes:
>Fergus Henderson wrote:
>>
>> For floating-point types, you can use an inline function.
>>
>> For integer types, an inline function doesn't work, because
>> you can't use an inline function in places where an integral
>> constant expression is required.
>
>Thank you for the explanation, but I can't agree with the argument;
>You mean that because I can write
>
>class B {
>public:
> float pi() const {
> static float _pi = 3.1415927;
> return _pi;
> }
> // ...
>};
I wouldn't write it like that. I'd just write it like this:
class B {
public:
static float pi() { return 3.1415927; }
// ...
};
This is not much worse than your proposed alternative:
>class A {
>public:
> static const float pi = 3.1415927;
> // . . .
>};
[...]
>And what about consistency?
>This asymmetry seems very counter-intuitive.
This is a reasonable argument.
The counter-argument is that allowing it increases the difficulty
of implementation. Maybe for C++0X.
>Furthermore, compile-time floating-point constants are useful
>e.g. for the initialization of other constants.
You can still write
static const float two_pi = 2 * pi();
or
static float two_pi() { return 2 * pi(); }
in standard C++.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/22 Raw View
On 21 Nov 97 14:53:48 GMT, Theodore Todorov <todorov@sbghp10.in2p3.fr>
wrote:
>Fergus Henderson wrote:
>>
>> Theodore Todorov <todorov@sbghp10.in2p3.fr> writes:
>>
>> >Is there a foundamental reason why in-class initialization of static
>> >constants is limited to integral types? Floating-point type constants
>> >are very convenient in classes for numerical libraries, and I can't
>> >see a reason for treating integral and floating-pint built-in types
>> >differently in this respect.
>>
>> For floating-point types, you can use an inline function.
>>
>> For integer types, an inline function doesn't work, because
>> you can't use an inline function in places where an integral
>> constant expression is required.
>>
>Thank you for the explanation, but I can't agree with the argument ...
>This asymmetry seems very counter-intuitive.
>
>Furthermore, compile-time floating-point constants are useful
>e.g. for the initialization of other constants.
The actual question is why floating-point constants have second-class
(or maybe third-class) privileges.
The reason is that floating point varies widely across systems, and
that the target of a C++ program may be different from the system used
to compile the program.
If the concept of floating-point constant is to mean anything, the
function foo must return the same result whether compiled on the
target system or cross-compiled from some other system.
const double onethird = 1.0/3.0; // compile time constant?
double quotient(double n, double d) {
return n/d; // run-time computation
}
bool foo() {
return onethird == quotient(1.0, 3.0);
}
In order to satisfy such requirements, the host would have to exactly
duplicate all floating point operations on the target system.
In writing the C standard, the C Committee elected not to place that
burden on all compilers, and the C++ Committee elected not to make
stronger requirements than C does. Thus, a cross-compiler can defer
computing the value of "onethird" until run time.
---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/22 Raw View
Darron Shaffer wrote:
> This difficulty that the standard is trying to avoid is the
> evaluation of floating point expressions at compile time.
This is up to the implementations. Some compilers do
compile time evaluation of floating points when then can.
> The reason
> for avoiding this is cross-compilation:
>
> const float comptime = 3.14159 / 4;
>
> float runtime = 3.14159;
> runtime /= 4;
>
> if (comptime != runtime)
> cerr << "compile time math not bit-for-bit accurate.";
>
> They could have loosened the rules somewhat by defining a floating
> point constant expression as being a floating point literal -- no
> operations allowed.
There is no such as a floating point constant expression, so there
are no rules about it.
> While this would have been another difference from C, I think it might
> have been a good idea.
The compiler is free to compute exactly any expression at
compile time under the as-if rule.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Robert G. Bryan" <RobertBryan@worldnet.att.net>
Date: 1997/11/22 Raw View
Bill Gibbons <bill@gibbons.org> wrote in article
<bill-1911972146530001@bgibbons.vip.best.com>...
> In article <6509ku$g2m@bgtnsc03.worldnet.att.net>, "Robert G. Bryan"
> <RobertBryan@worldnet.att.net> wrote:
>
> This was added several years ago. Static integral/enum const data
> members can have integral/enum constant initializers within the class.
>
> Originally, the static data member still had to be defined outside the
> class (without an initializer) because all static data members had to
> be defined outside the class, to statically allocate memory for them.
>
> But that restriction was also lifted - static data members need not be
> defined outside the class unless they are used in a manner which
> requires that their address be taken. So uses as a compile-time
> constant do not require the out-of-class definition.
>
> This is now a perfectly valid program:
>
> struct A {
> static const int size = 10;
> int array[size];
> };
>
> int main() {
> A a;
> return 0;
> }
>
> and has been for some time now. Of course not all compilers actually
> implement this yet.
>
>
> -- Bill Gibbons
> bill@gibbons.org
I'm using MS Visual C++ 5.0.
I tried adding the following line to a class:
static const int cTest1 = 1;
The compiler complained:
error C2258: illegal pure syntax, must be '= 0'
error C2252: 'cTest1' : pure specifier can only be specified for functions
Just for fun, I tried altering the line to:
static const int cTest1 = 0;
The compiler was kind enough to eliminate the first error message, but
still kicked out the 2nd error message.
When I changed the line to:
static const int cTest1;
Along with an initialization line after the class definition:
const int Cards::cTest1 = 1;
It compiled with no problems. So, in your opinion, is the compiler in
conformity with the standard?
I discovered an easy work around to this problem. If the constant is
defined before the class definition, for example:
static const int cTest1 = 10;
class Cards
{
char cTest2[cTest1];
...
}
Compiles just fine.
Question #2: I would like to be able to do the following inside a class:
static const char *pColors = "Red Blue Black";
or
static const char *pColors[] = {"Green", "Blue", "Yellow");
Does the C++ standard support this? Or, can I say:
static const char *pColors;
Then after the class definition add a line like:
const char * Cards::pColors = "Red Blue Black";
Again, I tried this same scenario with MSVC++ 5.0 and the linker this time
complained:
cards.obj : error LNK2005: "public: static char const * const
Cards::pColors" (?pColors@Cards@@2PBDB) already defined in Low Jack.obj
LowJack.cpp is the file that includes the cards.h header file. pColors is
not defined anywhere else.
Again, as a work-around, placing the declaration of pColors outside the
class eliminates the problem.
Robert Bryan
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bill@gibbons.org (Bill Gibbons)
Date: 1997/11/24 Raw View
In article <655qep$5bl@bgtnsc02.worldnet.att.net>, "Robert G. Bryan"
<RobertBryan@worldnet.att.net> wrote:
> > ...
> > But that restriction was also lifted - static data members need not be
> > defined outside the class unless they are used in a manner which
> > requires that their address be taken. So uses as a compile-time
> > constant do not require the out-of-class definition.
>
> I'm using MS Visual C++ 5.0.
> I tried adding the following line to a class:
>
> static const int cTest1 = 1;
>
> The compiler complained:
>
> error C2258: illegal pure syntax, must be '= 0'
> error C2252: 'cTest1' : pure specifier can only be specified for functions
>
> When I changed the line to:
>
> static const int cTest1;
>
> Along with an initialization line after the class definition:
>
> const int Cards::cTest1 = 1;
>
> It compiled with no problems. So, in your opinion, is the compiler in
> conformity with the standard?
No, since it does not implement this particular language feature.
(The "pure syntax" message is about what one would expect for a compiler
which does not implement this language feature.)
> Question #2: I would like to be able to do the following inside a class:
>
> static const char *pColors = "Red Blue Black";
>
> or
>
> static const char *pColors[] = {"Green", "Blue", "Yellow");
>
> Does the C++ standard support this?
No. This was discussed when the compile-time constant case was
discussed, and rejected. It was also proposed for non-static data
members, as a way to provide an initializer for a particular member
to be used by every constructor. That has some merit - namely, writing
the initializer only once - but that proposal was rejected too.
> Or, can I say:
==> in a header file...
>
> static const char *pColors;
>
> Then after the class definition add a line like:
>
> const char * Cards::pColors = "Red Blue Black";
>
> Again, I tried this same scenario with MSVC++ 5.0 and the linker this time
> complained:
>
> cards.obj : error LNK2005: "public: static char const * const
> Cards::pColors" (?pColors@Cards@@2PBDB) already defined in Low Jack.obj
This could be a peculiarity of precompiled headers. As long as the
header is included only once, there is only one definition of the
static data member and the program is well-formed.
If the definition really must go in a header file which is included more
than once, you have to make it into a template and rely on the template
instantiation mechanism to create a single definition. That's a lot of
machinery just to get a static data member defined, but it works.
-- Bill Gibbons
bill@gibbons.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1997/11/25 Raw View
--Multipart_Mon_Nov_24_14:07:42_1997-1
Content-Type: text/plain; charset=US-ASCII
Valentin Bonnard <bonnardv@pratique.fr> writes:
> Darron Shaffer wrote:
>
> > This difficulty that the standard is trying to avoid is the
> > evaluation of floating point expressions at compile time.
>
> This is up to the implementations. Some compilers do
> compile time evaluation of floating points when then can.
>
> > The reason
> > for avoiding this is cross-compilation:
> >
> > const float comptime = 3.14159 / 4;
> >
> > float runtime = 3.14159;
> > runtime /= 4;
> >
> > if (comptime != runtime)
> > cerr << "compile time math not bit-for-bit accurate.";
> >
> > They could have loosened the rules somewhat by defining a floating
> > point constant expression as being a floating point literal -- no
> > operations allowed.
>
> There is no such as a floating point constant expression, so there
> are no rules about it.
>
What I was suggesting was adding these, which would allow:
class B
{
const float pi = 3.14159;
...
};
but not:
class C
{
const float pi_over_4 = 3.14159 / 4;
}
Which preserves the current reluctance to force a vendor to emulate
target machine floating point.
--Multipart_Mon_Nov_24_14:07:42_1997-1
Content-Type: text/plain; charset=US-ASCII
__ __ _
_ ) ___ _\
__) __ \ Enterprise Middleware Solutions Darron J. Shaffer
BEA Systems Inc. Sr. Software Engineer
17101 Preston Rd darron.shaffer@beasys.com
LB# 115, Ste 260 Voice: (972) 738-6137
Dallas, TX 75248 Fax: (972) 738-6111
http://www.beasys.com
--Multipart_Mon_Nov_24_14:07:42_1997-1--
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Robert G. Bryan" <RobertBryan@worldnet.att.net>
Date: 1997/11/20 Raw View
Currently, the C++ standard specifies that a constant declared in a class
can not be initialized in that class. It must either be intialized in the
constructor initialization list, or for a static const - initialized
outside the class. One of the reasons for this, as I understand it, is in
order to maintain backward compatibility with C constants. Yet, it seems to
me to be somewhat cumbersome to define a constant on 2 different lines, let
alone 2 different files (the header file for the declaration and the .cpp
file for the constructor)...
So, since the current syntax is differentiating a C constant from a C++
constant, why not come up with a little different syntax for declaring and
initializing a C++ on the same line? For example:
const int Size = 5;
would still initialize a C constant to 5. A different syntax (for example):
const int Size := 5;
or
static const int Size := 5;
would initialize the C++ constant to 5. This seems to be such an obvious
idea. Perhaps there is some reason involving inheritance why something like
this can't be done for either static or non-static class constants.
Anybody have any ideas?
Robert Bryan
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bill@gibbons.org (Bill Gibbons)
Date: 1997/11/21 Raw View
In article <6509ku$g2m@bgtnsc03.worldnet.att.net>, "Robert G. Bryan"
<RobertBryan@worldnet.att.net> wrote:
> Currently, the C++ standard specifies that a constant declared in a class
> can not be initialized in that class. It must either be intialized in the
> constructor initialization list, or for a static const - initialized
> outside the class. One of the reasons for this, as I understand it, is in
> order to maintain backward compatibility with C constants. Yet, it seems to
> me to be somewhat cumbersome to define a constant on 2 different lines, let
> alone 2 different files (the header file for the declaration and the .cpp
> file for the constructor)...
>
> So, since the current syntax is differentiating a C constant from a C++
> constant, why not come up with a little different syntax for declaring and
> initializing a C++ on the same line? For example:
>
> const int Size = 5;
>
> would still initialize a C constant to 5. A different syntax (for example):
>
> const int Size := 5;
>
> or
>
> static const int Size := 5;
>
> would initialize the C++ constant to 5. This seems to be such an obvious
> idea. Perhaps there is some reason involving inheritance why something like
> this can't be done for either static or non-static class constants.
>
> Anybody have any ideas?
This was added several years ago. Static integral/enum const data
members can have integral/enum constant initializers within the class.
Originally, the static data member still had to be defined outside the
class (without an initializer) because all static data members had to
be defined outside the class, to statically allocate memory for them.
But that restriction was also lifted - static data members need not be
defined outside the class unless they are used in a manner which
requires that their address be taken. So uses as a compile-time
constant do not require the out-of-class definition.
This is now a perfectly valid program:
struct A {
static const int size = 10;
int array[size];
};
int main() {
A a;
return 0;
}
and has been for some time now. Of course not all compilers actually
implement this yet.
-- Bill Gibbons
bill@gibbons.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <petebecker@acm.org>
Date: 1997/11/21 Raw View
Robert G. Bryan wrote:
>
> Currently, the C++ standard specifies that a constant declared in a class
> can not be initialized in that class. It must either be intialized in the
> constructor initialization list, or for a static const - initialized
> outside the class.
That was changed a couple of years ago.
> One of the reasons for this, as I understand it, is in
> order to maintain backward compatibility with C constants. Yet, it seems to
> me to be somewhat cumbersome to define a constant on 2 different lines, let
> alone 2 different files (the header file for the declaration and the .cpp
> file for the constructor)...
>
> So, since the current syntax is differentiating a C constant from a C++
> constant, why not come up with a little different syntax for declaring and
> initializing a C++ on the same line?
Because that's not the reason that you weren't allowed to do it. In any
event, what you're asking for is there:
class C
{
public:
static const int size = 3;
int array[size];
};
const int C::size;
-- Pete
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Theodore Todorov <todorov@sbghp10.in2p3.fr>
Date: 1997/11/21 Raw View
Bill Gibbons wrote:
>
> In article <6509ku$g2m@bgtnsc03.worldnet.att.net>, "Robert G. Bryan"
> <RobertBryan@worldnet.att.net> wrote:
>
> > Currently, the C++ standard specifies that a constant declared in a class
> > can not be initialized in that class. It must either be intialized in the
> > constructor initialization list, or for a static const - initialized
> > outside the class. One of the reasons for this, as I understand it, is in
> > order to maintain backward compatibility with C constants. Yet, it seems to
> > me to be somewhat cumbersome to define a constant on 2 different lines, let
> > alone 2 different files (the header file for the declaration and the .cpp
> > file for the constructor)...
> >
>
> This was added several years ago. Static integral/enum const data
> members can have integral/enum constant initializers within the class.
>
> Originally, the static data member still had to be defined outside the
> class (without an initializer) because all static data members had to
> be defined outside the class, to statically allocate memory for them.
>
> But that restriction was also lifted - static data members need not be
> defined outside the class unless they are used in a manner which
> requires that their address be taken. So uses as a compile-time
> constant do not require the out-of-class definition.
Is there a foundamental reason why in-class initialization of static
constants is limited to integral types? Floating-point type constants
are very convenient in classes for numerical libraries, and I can't
see a reason for treating integral and floating-pint built-in types
differently in this respect.
Teddy Todorov
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/21 Raw View
Theodore Todorov <todorov@sbghp10.in2p3.fr> writes:
>Is there a foundamental reason why in-class initialization of static
>constants is limited to integral types? Floating-point type constants
>are very convenient in classes for numerical libraries, and I can't
>see a reason for treating integral and floating-pint built-in types
>differently in this respect.
For floating-point types, you can use an inline function.
For integer types, an inline function doesn't work, because
you can't use an inline function in places where an integral
constant expression is required.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/21 Raw View
Theodore Todorov wrote:
> Is there a foundamental reason why in-class initialization of static
> constants is limited to integral types? Floating-point type constants
> are very convenient in classes for numerical libraries, and I can't
> see a reason for treating integral and floating-pint built-in types
> differently in this respect.
Only integral values can appear in integral constant
expression (except things such as int (3.14)), that's
the official reason.
It think all types should be allowed, but it's only my
point of view. I also think that the definition:
type X::static_member;
should be optionnal.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: john@PROBLEM_WITH_INEWS_DOMAIN_FILE.UCAR.EDU (John W. Schwegler)
Date: 1997/11/21 Raw View
Theodore Todorov (todorov@sbghp10.in2p3.fr) wrote:
[omitted]
I agree that it would be nice to be able to initialize constants of other
built-in types the same as is done for integral values now. I do not see
the need for a distinction in that manner.
However, why this:
: class B {
: public:
: float pi() const {
: static float _pi = 3.1415927;
: return _pi;
: }
: // ...
: };
instead of:
class B {
public:
float pi() const { return 3.1415927; }
}
I suppose a decent compiler will optimize this out in many circumstances.
-john
--
______________________________________________________________________________
John Schwegler - replies to: john@flower.aud.temple.edu
Hofstadter's Law: It always takes longer than you expect,
even when you take Hofstadter's Law into account.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Theodore Todorov <todorov@sbghp10.in2p3.fr>
Date: 1997/11/21 Raw View
Fergus Henderson wrote:
>
> Theodore Todorov <todorov@sbghp10.in2p3.fr> writes:
>
> >Is there a foundamental reason why in-class initialization of static
> >constants is limited to integral types? Floating-point type constants
> >are very convenient in classes for numerical libraries, and I can't
> >see a reason for treating integral and floating-pint built-in types
> >differently in this respect.
>
> For floating-point types, you can use an inline function.
>
> For integer types, an inline function doesn't work, because
> you can't use an inline function in places where an integral
> constant expression is required.
>
Thank you for the explanation, but I can't agree with the argument;
You mean that because I can write
class B {
public:
float pi() const {
static float _pi = 3.1415927;
return _pi;
}
// ...
};
the possibility to write
class A {
public:
static const float pi = 3.1415927;
// . . .
};
is not needed, even though I can (or will be able to) write
class A {
public:
static const int age_of_the_captain = 55;
// . . .
};
because the int constant might be needed at compile time?
And what about consistency?
This asymmetry seems very counter-intuitive.
Furthermore, compile-time floating-point constants are useful
e.g. for the initialization of other constants.
Teddy Todorov
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1997/11/21 Raw View
--Multipart_Fri_Nov_21_13:53:15_1997-1
Content-Type: text/plain; charset=US-ASCII
Theodore Todorov <todorov@sbghp10.in2p3.fr> writes:
> You mean that because I can write
(examples slightly modified)
>
> class B {
> public:
> float piov4() const {
> static float _piov4 = 3.1415927 / 4; // Float math at RUNTIME
> return _pi;
> }
> // ...
> };
>
> the possibility to write
>
> class A {
> public:
> static const float piov4
> = 3.1415927 / 4; // Float math at COMPILE TIME
> // . . .
> };
>
> is not needed, even though I can (or will be able to) write
>
> class A {
> public:
> static const int age_of_the_captain = 55;
> // . . .
> };
>
> because the int constant might be needed at compile time?
> And what about consistency?
> This asymmetry seems very counter-intuitive.
>
> Furthermore, compile-time floating-point constants are useful
> e.g. for the initialization of other constants.
>
This difficulty that the standard is trying to avoid is the
evaluation of floating point expressions at compile time. The reason
for avoiding this is cross-compilation:
const float comptime = 3.14159 / 4;
float runtime = 3.14159;
runtime /= 4;
if (comptime != runtime)
cerr << "compile time math not bit-for-bit accurate.";
They could have loosened the rules somewhat by defining a floating
point constant expression as being a floating point literal -- no
operations allowed.
While this would have been another difference from C, I think it might
have been a good idea.
--Multipart_Fri_Nov_21_13:53:15_1997-1
Content-Type: text/plain; charset=US-ASCII
__ __ _
_ ) ___ _\
__) __ \ Enterprise Middleware Solutions Darron J. Shaffer
BEA Systems Inc. Sr. Software Engineer
17101 Preston Rd darron.shaffer@beasys.com
LB# 115, Ste 260 Voice: (972) 738-6137
Dallas, TX 75248 Fax: (972) 738-6111
http://www.beasys.com
--Multipart_Fri_Nov_21_13:53:15_1997-1--
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]