Topic: zzzzzzzzzzzzzzzz No Subject
Author: No Author
Date: No Date Raw View
and in 3.7.3.2 Deallocation functions [basic.stc.dynamic.deallocation]
"1 Deallocation functions shall be class member functions or global
functions; a program is ill-formed if deallocation
functions are declared in a namespace scope other than global scope or
declared static in global
scope."
'operator new' and 'operator delete' must be declared in a global scope.
But, from other side, we can't declare they as friend of any class in
a namespace scope other than global scope, because:
7.3.1.2 Namespace member definitions [namespace.memdef]
"3 ... If a friend declaration in a non-local class first declares
a class or function the friend class or function is a member of the
innermost
enclosing namespace. ... When looking for a prior declaration of a class
or a function declared as a friend, and when the name of the friend class or
function is neither a qualified name nor a template-id, scopes outside the
innermost enclosing namespace
scope are not considered."
So, for solve this problem we need to put forward declaration of friend
'operator new' and 'operator delete' to global scope and refer to it in
friend
declaration:
namespace N
{
class C
{
public: enum E {};
friend void* ::operator new(size_t, E);
friend void ::operator delete(void*, E);
};
}
But we can't make forward declaration for this operators because they uses
the type internally declared in class C. Vicious circle.
Some compilers, such as MS VC 6.0 - MS VC 2003, allows workaround:
namespace N
{
class C
{
public: enum E {};
friend void* operator new(size_t, E);
friend void operator delete(void*, E);
};
}
inline
void* operator new(size_t sz, N::C::E e)
{
return N::operator new(sz, e);
}
void foo()
{
N::C::E e;
N::C* ptr = new(e) N::C();
}
but this behavior is not standard compliant.
RESOLUTION:
The best way, IMHO, introduce a new syntax addendum for friend declaration
that allow explicitly inject name of friend function to any desired
namespace scope.
Or, to fix only the described problem, change the text of paragraph 3 of
clause 7.3.1.2 and add an exception to the rule for friend
allocation/deallocaton function.
A scope for such functions must correspond with clauses 3.7.3.1/3.7.3.2.
Dmitriy Litskalov
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: No Author
Date: No Date Raw View
Assign (24 at addr2) from (28 at addr3)
Compare (28 at addr2) to (20 at addr1): Different
Assign (28 at addr3) from (32 at addr4)
Compare (32 at addr3) to (28 at addr2): Equal
Assign (32 at addr3) from (40 at addr5)
Compare (40 at addr3) to (28 at addr2): Different
10 20 28 40
Destroy (40 at addr5)
Destroy (32 at addr4)
Destroy (40 at addr3)
Destroy (28 at addr2)
Destroy (20 at addr1)
Destroy (10 at addr0)
Or if the removals are deferred:
Compare (28 at addr3) to (24 at addr2): Equal
Compare (32 at addr4) to (28 at addr3): Equal
Compare (40 at addr5) to (32 at addr4): Different
Assign (24 at addr2) to (40 at addr5)
10 20 40
Destroy (40 at addr5)
Destroy (32 at addr4)
Destroy (28 at addr3)
Destroy (40 at addr2)
Destroy (20 at addr1)
Destroy (10 at addr0)
I think an implementation which did the following would also be legal:
Compare (28 at addr3) to (20 at addr1): Different
Assign (24 at addr2) from (28 at addr3)
Compare (32 at addr4) to (28 at addr2): Equal
Compare (40 at addr5) to (28 at addr2): Different
Assign (28 at addr3) to (40 at addr5)
10 20 28 40
Destroy (40 at addr5)
Destroy (32 at addr4)
Destroy (40 at addr3)
Destroy (28 at addr2)
Destroy (20 at addr1)
Destroy (10 at addr0)
The implementation I looked at would do the following:
Construct 10 at addr0
Construct 20 at addr1
Construct 24 at addr2
Construct 28 at addr3
Construct 32 at addr4
Construct 40 at addr5
Copy (10 at addr6) from (10 at addr0)
Compare (10 at addr6) to (20 at addr1): Different
Assign (10 at addr6) to (20 at addr1)
Compare (20 at addr6) to (24 at addr2): Equal
Compare (20 at addr6) to (28 at addr3): Different
Assign (24 at addr2) to (28 at addr3)
Assign (20 at addr6) to (28 at addr3)
Compare (28 at addr6) to 32 at addr4): Equal
Compare (28 at addr6) to (40 at addr5): Different
Assign (28 at addr3) to (40 at addr5)
10 20 32 40
Destroy (40 at addr5)
Destroy (32 at addr4)
Destroy (40 at addr3)
Destroy (28 at addr2)
Destroy (20 at addr1)
Destroy (10 at addr0)
I believe that the Copy is not legal. From section 25, paragraph 5, we
know that the iterators must be mutable. However, nowhere is it required
that std::iterator_traits<iterator>::value_type must be
CopyConstructible.
My original claim was that the only requirement was that pred return a
type convertible to bool. ApproxEqual meets that requirement.
I've reluctantly come to agree that the standard does not specify the
order in which the comparisons occur relative to the removals.
Therefore, it's dangerous to provide predicates for which that order
would affect the results. ApproxEqual is such a predicate.
Pete suggested that the behavior is undefined unless the predicate
defines an equivalence class. This would guarantee that the order of the
removals doesn't matter, but it's a little bit stronger requirement than
is needed to make that guarantee. ApproxEqual doesn't meet that
requirement.
I claim that the argument Pete was using must, if valid, require that
the predicate define the same equivalence classes as std::equal_to<>
(from which I concluded that his argument can't be valid). ApproxEqual
certainly doesn't meet that requirement.
[ 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: No Author
Date: No Date Raw View
Now, if I take the word "equal" as constraining the predicate, rather
than being simply verbal shorthand for it, then I can derive the
requirements that std::equal_to<> must be instantiatiable for the given
type, and that the predicate must return false iff std::equal_to<> would
return false.
How do you derive contraints that fall somewhere in between these two
extremes?
[ 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: No Author
Date: No Date Raw View
[ ... ]
> By symmetry, declaring a friend function following a 'public:'
> modifier within a class declaration would limit the function's
> access to only the public members of the class.
Which is equivalent to not being a friend at all.
IMO, anything along this general line is a mistake. A friend function
is really a part of the class that for some reason or other needs to
be physically separated from the rest of the class declaration. As
such, trying to restrict its access to the internals of the class
doesn't really make any more sense than trying to restrict particular
member functions to only being able to access part of the class.
When/if you run into a situation where either of these seems
desirable, I think it's a strong indication that the class has been
poorly designed. If a member or friend should be restricted to only
being able to manipulate some of the class' internals, but not other
parts, that seems to me an indication that what you've presently
designed as one class should probably be two (or more) classes, and
the member/friend should have access to only one of those classes.
IOW, I think it's a clever solution in search of a problem.
Unfortunately, adding the solution to the standard language is likely
to encourage the matching problem, which I'd consider a poor idea.
--
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: No Author
Date: No Date Raw View
[Moderator's note: no, `void' in a parameter list is the same
as having no parameters at all. It does not indicate a single
parameter of type `void'. -moderator (fjh).]
"James W. McKelvey" wrote:
> The simple code below results in a link error with both GCC 2.95.1 and the CC
> Sun compiler:
>
> /bin/ld: Undefined symbols:
> Pattern::~A(void)
>
> Since it fails on two different compilers I'm hesitant to report it as a GCC
> bug, but I can't see the problem. If I change the pure virtual function to
> something other than a destructor, it works fine.
>
> > >
> > > class A
> > > {
> > > public:
> > > virtual ~A(void) = 0;
> > > };
> > >
> > > class B : public A
> > > {
> > > public:
> > > virtual ~B(void)
> > > {
> > > };
> > > };
> > >
> > > int main(void)
> > > {
> > > B x;
> > >
> > > return 0;
> > > }
>
> Checking the standard, 10.4 says" "A pure virtual function need be defined
> only if explicitly called with the qualified-id syntax."
>
> And 12.4(7) says "A destructor can be declared virtual or pure virtual; if
> any objects of that class or any derived class are created in the program,
> the destructor shall be defined."
>
> This is somewhat of a contradiction. Does "shall be defined" mean "must be
> defined"? Or does it mean that a default destructor will be invented by the
> 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
"The Unicode Standard provides 65 code values for the representation of
control characters."
[snip]
"Programs that conform to the Unicode Standard may treat these 16-bit
control codes in exactly the same the same way as they treat their 7- and
8-bit equivalents in other protocols, such as ISO.IEC 2022 and ISO/IEC 6429.
Such usage constitutes a higher level protocol and is beyond the scope of
the Unicode Standard."
My reading is that this means that Unicode represents control characters,
but what you do with them is your business. I think C should give you a way
of expressing commonly used control characters and not dictate what you do
with them. This appears to be at odds with the way the C standard is
written. Sigh.
>and that SI and SO
>are deprecated by ISO 4873 (or something like that), in favor of
>LS0/LS1 etc.
Could be. I'm not familiar with ISO 4873 or LS0/LS1. SI and SO are used in
some Japanese coding schemes.
David J. Littleboy
Tokyo, Japan
davidjl <at> gol <dot> 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: No Author
Date: No Date Raw View
John Keenan
[ 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: No Author
Date: No Date Raw View
We have two options:
progressively remove the use of raw pointers from code (and change the
way we teach newcomers)
provide some mechanism to protect objects from deletion through pointers
passed as arguments.
I think the only real benefit of this whole discussion is that it has
clarified in my mind (and hopefully the minds of many other readers)
what the real issues are. That is what we should focus on rather than
sterile arguments about whether the Standards Committees should or
should not have made a change. (note that in order for this change to
happen much more than a simple majority of the experts voting had to
agree - as you well know the mechanisms for voting on changes to a
working paper are aimed at supporting consensus decisions)
Francis Glassborow Journal Editor, 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: No Author
Date: No Date Raw View
Prior to the breakage, many interfaces were designed under the
promise that handing over a pointer-to-const could be safe.
The code didn't break, but the promise did, and the change
broke all the many designs that depended on the promise.
> Further, I disdain his repeated suggestion that all
> arguments contrary to his opinion are illogical.
Only the contrary arguments I have _seen_ were illogical. More to
the point, they have all carefully avoided addressing the software
engineering consequences of the change. I.e. it doesn't so much matter
that they were illogical, because they have also been irrelevant.
Carefully avoiding engineering consequences does not lead to good
design decisions, or sound arguments. Again, I am disappointed
to find otherwise clear-thinking people indulging this way.
--
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: No Author
Date: No Date Raw View
--
--------------
siemel b naran
--------------
[ 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: No Author
Date: No Date Raw View
\v (vertical tab) Moves the active position to the initial position
of the next vertical tabulation position.
Now, granted, there don't seem to be similar words in the C++ standard,
but since this is cross-posted to comp.std.c, we ought not to limit
ourselves to legalistic interpretations of the C++ standard in order to
avoid taking responsibility. <g> But even if you're into this sort of
dodging, how long do you think you'll continue to have customers if your
library clears the screen when it encounters a \t and mine moves to the
next tab position?
--
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: No Author
Date: No Date Raw View
\a (alert) Produces an audible or visible alert. The active position shall
not be changed.
\b (backspace) Moves the active position to the previous position on the
current line. If the active position is at the initial position of
a line, the behavior is unspecified.
....
--
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: No Author
Date: No Date Raw View
> I would love to be part of the C++ Committee -- but I'm just a
> poor ol' writer and consultant, without a big company to pay my
> way. See, I got these three kids to feed, and a wife, and a guinea
> pig, and a grumpy old truck...
The above was *not* a suggestion that the committee consists of elitists or
rich folk or that I'm too cheap to join. See, it was a joke, ya know, a
piece of self-deprecating humor. Surely people noticed the reference to the
guinea pig...
Actually, I've just been too damned busy to join an ANSI committee --
although I'm thinking about doing so now. I know the basics on how the ANSI
committee works, but can anyone direct me to a web site or FAQ that
describes the requirements for and obligations of membership?
[ moderator's note: See the FAQ for this newsgroup. -sdc ]
--
* Scott Robert Ladd
* Coyote Gulch Productions - http://www.coyotegulch.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: No Author
Date: No Date Raw View
For example, one could write
T const* f() { T const* p = new T; g(p); return p; }
and, without knowing anything about g() or about f()'s caller (except
that they do not use casts), know that p was still usable and returnable.
Now, all bets are off. Const is broken, and the best we can hope for
is for coding standards and compilers to warn against deleting via a
pointer-to-const.
In practice, library designers, perforce, implement interfaces as if
the change had not happened, because to wrap every pointer up in a
class object just to enforce constness would be too messy. The effect
is that a common error that previously was easily detected at compile
time is no longer easily detectable at all.
That otherwise-careful committee members were swayed by such specious
arguments in this case -- as they were, also, in the case of delete-
expressions applied to pointers to incomplete types -- seems to me a
cause for deep concern. Perhaps in future language design discussions,
the "C++ Delete-Expression Fallacies" may be invoked when reasoning
threatens to go off the rails.
--
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: No Author
Date: No Date Raw View
struct POD {};
struch PODwithConst { const void *a; };
struct nonPOD {};
struct nonPODwithCtor { nonPODwithCTor(); };
we get...
1. POD* p01 = new POD;
The object pointed to by p01 (hereafter referred to using *p01 syntax)
has indeterminate value.
2. POD* const p02 = new POD;
PODwithConst* p03 = new PODwithConst;
In both cases, the program is ill-formed.
3. nonPOD* p04 = new nonPOD;
nonPODwithCtor* const p05 = new nonPODwithCtor;
*p04 and *p05 are default-initialized.
4. nonPOD* const p06 = new nonPOD;
This is an error, as nonPOD does not have a default constructor.
5. POD* p07 = new POD();
PODwithConst* p08 = new PODwithConst();
nonPOD* p09 = new nonPOD();
nonPODwithCtor* p10 = new nonPODwithCtor();
In all cases, default-initialization is performed.
Some of these results are guaranteed by the fact that a POD cannot, by
definition, don't have a constructor.
--
Jeff Rife |
19445 Saint Johnsbury Lane | http://www.nabs.net/Cartoons/Dilbert/ActualCode.gif
Germantown, MD 20876-1610 |
Home: 301-916-8131 |
Work: 301-770-5800 Ext 5335 |
[ 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: No Author
Date: No Date Raw View
- define three typedef float_complex, etc has in EC++, in C and C++
> > > > . Variable-length arrays (VLAs)
>
> > > A pure extension, but with possible problems when added to C++.
>
> > Allowing it only on POD or C struct would cause no more
> > problems than in C IMO.
>
> With perhaps the added restriction that you cannot inherit from a class
> which contains a VLA.
You cannot have VLAs in structs.
> Which is a bothersome restriction: one frequent
> technique for adhering to C API's is to derive from the C structure in
> the C++ part.
I would allow one to derive from X iff he is allowed to use X as
a member in C++ iff he is allowed to use X as a member in C9X.
--
Valentin Bonnard
[ 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: No Author
Date: No Date Raw View
There is a compile time cost because the compiler must construct a
more elaborate virtual table. But given that the compiler has to
already do complicated stuff like parse template template parameters,
member templates, namespaces, etc, I think the overhead is relatively
small.
--
----------------------------------
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: No Author
Date: No Date Raw View
void fn(string);
void gn(char *);
int main() {
fn("C++"); // passes a string by value
gn("C"); // passes a pointer to a C style array of const char
(and issues a warning before doing the conversion to a non-const array)
If we could add a rule that C++ strings are preferred ... Oh well the
idea is full of holes.
Francis Glassborow Journal Editor, 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: No Author
Date: No Date Raw View
template<class T>
void myFunction(iterable<T> *anIterable) // anIterable is a vector<T>, given
in its base class
{
iterable<T>::iterator it; // this is a virtual iterator type, since it must
work as a vector iterator
it=anIterable->begin(); // this is a dispatched call, since anIterable is
not be final. It returns the iterator, which dispatches as a
vector<>::iterator.
....
// or I somehow figure out, that the iterable is a vector<T> for example...
final vector<T> *anVector = dynamic_cast<final Vector<T>*> anIterable;
if (anVector)
// now I can use it directly.
vector<T>::iterator it; // the iterator from vector inherits from
iterable<T> and is marked 'final' and therfore inlined.
it=anVector->begin(); // non dispatched call.
}
}
What I can't see is:
How does that virtual iterator works?
template<class T>
iterable<T>
{
...
typedef ??? iterator;
...
};
1. There are no virtual types. The iterator simply has to know about ALL the
iterator types that can be found in the derives of iterable<> and has to
wrap them somehow.
OR
2. the iterator in iterable<> is the baseclass for the iterators in
vector<>, set<> etc.. vector<> will define a new iterator,
vector<>::iterator : public iterable<T>::iterator
Then we would need code like that:
iterable::<T> *it; // polymorphic iterator cannot live on the stack.
it=anIterable->begin(); // allocates a new vector<>::iterator, because
begin() dispatched to vector
... use it ..
delete it;
For the direct,fast case, we surely don't want to allocate an iterator on
the heap so we have:
vector<T>::iterator it=anVector->begin2(); // we cannot overload with
the return type..
But if we're starting this, we could also start making a virtual and a
non-virtual interface to vector<>
So, where am I wrong?
[ 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: No Author
Date: No Date Raw View
: Should this be a defect report?
I think that the silent answer you are getting is, "Only if you feel
strongly enough about it to draft one."
I have also noticed that question tends to stop a thread.
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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
I really don t know what s the story with virtual member functions, but
it looks to me that they can be FORWARD declared too.
At my opinion this possibility would improve the encapsulation
possibilities and would decrease build dependencies.
This proposal is also fully backward compatible with existing standard,
too.
So, what do you think?
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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: No Author
Date: No Date Raw View
Whether or not this is OK depends on what Oracle tells you about longjmp-ing
across their library. In this sense, longjmp is a lot like exceptions: If
you want to throw across a library, it needs to be written to support it. If
Oracle doesn't document it, you have to assume that it's not OK.
> 2nd solution: call a C++ function from my_C_function().
> Would it be possible at all? Is it possible to pass a C++ callback
> function to some C code? I guess the answer is 'no'. But there might be
> a way to tell the C++ compiler that some function should have a C name
> (without type information), while being written in C++.
exactly. You do that by writing:
extern "C" my_Cpp_function() { /* c++ code */ }
> If so, would it work? I mean, we are throwing from a C++ function
> called by a C function called by some *&^@ Oracle-specific C code called
> by a C function called by a C++ function (where we would like to come
> back, because the catcher is here!)
In general, throwing across code compiled with a 'C' compiler would produce
undefined results, though your compiler vendor may tell you differently (for
your particular implementation). I'm almost certain that the Oracle code is
written in straight 'C', not to mention the code you're using to interface
with it, so this is probably not a good idea.
> 3rd solution: call setjmp in the C++ code, and pass the argument for
> longjmp to the C functions. Whenever an error occurs, call a longjmp
> with this argument.
> Would it work? Is setjmp supported in C++.
Yes, but inadvisable. This is no better than solution 1, and we know what
the problems are with that. Also, in general setjmp may confuse optimizers.
I suppose if you declare all local variables where the setjmp is used as
'volatile' you may avoid that pitfall.
> When we write "would it work", it means "in compliance with the
> standard". We can find some implementations on which it works, and some
> others on which it does not work... It's just a matter of "how should we
> be doing that?"
The best solution I can give you without more information is (unfortunately)
not thread-safe. You can use a global variable in which you store the error
information from the error callback. Wrap all of your DB accesses in C++
which checks the global variable afterwards and throws an appropriate
exception. Now, if your error callbacks can actually take an argument as you
seem to imply above, you can solve the thread-safety problem by using a
local variable whose address is passed to the error callback.
Hope this helps,
Dave
[ 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: No Author
Date: No Date Raw View
The restrictions on cv-qualification, and the manner in which the
cv-qualifiers of the operands are combined to produce the cv-qualifiers
of the result, are the same as the rules for E1.E2 given in 5.2.5.
This is a bit terse; worse yet, to find the restriction you have to look
at the cross-reference in 5.2.5 paragraph 4:
... The expression can be used only as the left-hand operand of a member
function call (9.3).
then look at 9.3.2 paragraph 4:
A cv-qualified member function can be called on an object-expression
(5.2.5) only if the object-expression is as cv-qualified or
less-cv-qualified than the member function.
(It would be better if 5.5/5 had a cross-reference directly to 9.3.2.)
Also note that cv-qualification of a function type is part of the type
itself, not tacked on as is it for objects. So it must be part of the
function declarator itself (see 8.3.5/4) For example:
typedef int X;
typedef const int CX1; // OK
typedef const X CX2; // OK
typedef void F();
typedef void CF1() const; // OK, but can only be used for members
typedef const F CF2; // ill-formed
F *PF; // OK
CF1 *PCF; // ill-formed
struct A { };
typedef F A::*PMF; // OK, if somewhat obscure
typedef CF1 A::*PCMF; // OK, but even more obscure
typedef const F A::*PCMF2; // ill-formed
Some compilers accept some of the ill-formed cases and/or reject some of
the well-formed cases.
-- 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
The parameter list (void) is equivalent to the empty parameter list.
In other places in the standard, when a transformation based on types occurs
(for example in 8.3.5/3, "The type of a function is determined using the
following rules. The type of each parameter is determined from its own
decl-specifier-seq and declarator....") there is a discussion of types.
But 8.3.4/2 does not say "if there is one parameter and its type is void",
but rather "The parameter list (void)...". So this is a syntactic
description of an alternate way to lexically write an empty parameter list.
I think the standard is sufficiently clear on this point.
Also, the standard committee explicitly considered a proposed extension
to the language to allow f(T) to describe a parameterless function when
T is a template parameter "void", and rejected the proposal.
-- 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
From one point of view, T deduced to be void.
Author: No Author
Date: No Date Raw View
So the question is what 8.3.5/2 applies to.
It clearly applies to non-template code. Eg,
int f(void); // ok
int f(int, void); // error
But does it apply to template code?
template <class T> int f(T t); // ok
int main() { f<void>(void); } // ok?
That is, can f<void>() be instantiated?
--
----------------------------------
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: No Author
Date: No Date Raw View
Filling in a char array is a very common task users face. Specified file
formats and external device communications frequently require formatting
of text and the use of fixed structures, and I am surprised that there is
no longer any way to use iostreams to directly write to user-allocated
memory.
[ 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: No Author
Date: No Date Raw View
Thus we have a strong case in favor of the rule that currently is standard.
OTOH lets have a look at our previous argument against that rule. Why should
passing a const pointer to a function imply that ownership(1) [=control of
lifetime] is not transferred, while passing a non-const pointer is
completely neutral in this respect. Proper lifetime management is up to the
developer in any case. The semantics of any function receiving a pointer as
a parameter as to whether this pointer will be deleted by the called context
or not must be specified, regardless of any const on this pointer. BTW: the
standard already provides a way to show that ownership is transferred,
namely auto_ptr.
In another post Nathan Myers writes:
>A local const variable is being destroyed with full knowledge of its
>creator, in the same context where it was created, and where it is
>lexically impossible to try to continue using it. Destruction in
>some random other context is in no wise equivalent.
Destruction in some random context is NEVER wise. But, as the language
doesnt protect you from doing that through a non-const pointer, why should
it do that for const pointers ?
>For an example,consider:
>
> void g(T const*);
> void f() { const T t; g(&t); }
>
>Without studying the implementation of g, we cannot tell anything about
>the safety of f, purely because of this one language design error.
Consider also:
void g(T *);
void f() { T t; g(&t); }
Without studying the implementation of g, we cannot tell anything about
the safety of this f either, regardless of this one 'language design
error'(?).
My summary of the preceding:
I still maintain as a style rule, that const pointers received from another
context *generally* should not be deleted. But I *generally* apply the same
rule to non-const pointers as well. When ownership of object lifetime is
transferred, I prefer using something like auto_ptr<>. Where it is
appropriate (usually hidden in a class, which often is a template
instantiation) I prefer being able to delete through a const pointer,
instead of resorting to const_cast or partial specialization on constness.
----------------------------------------------------------------------------
(*)
An exemplary case of the situation described, would be reference-counted
smart pointers. Lets look at a simple implementation:
template<class T>
class SmartPtr {
public:
... // skip a lot
~SmartPtr() { if (ptr_ && --ptr_->ref_count <= 0) delete ptr_; }
... // skip more
T* operator->() const { return ptr_; }
private:
T* ptr_;
};
It is meaningful to require ref_count to be a mutable member of T, as it is
not part of its externally visible state (there is no state left when the
object is deleted). Now, SmartPtr<T> and SmartPtr<T const> both do the right
thing: They share a reference count, they provide clients access as
specified by the template parameter, etc. . Why then should SmartPtr<T
const> be specialized to hold a (non-const) T* or to work with const_cast,
if its only 'non-const' access to T is to delete it when its time has come ?
[ 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: No Author
Date: No Date Raw View
> Currently, objects don't become const until the constructor completes
> and cease to be const once the destructor begins.
Quite so. I am comfortable with this. However, invoking operator delete()
is something that happens *before* the destructor begins, before the
object has ceased to be const, so it does not get through under that rule.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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: No Author
Date: No Date Raw View
Presumably, the stack container could theoretically be used to implement
the call stack (for potential recursion, etc.). In practice, the compiler
vendor would have to ensure that it is possible to call stack<> member
functions without creating infinite recursion. I suspect that it would be
simpler to emulate a private, limited stack within function "prolog" and
"epilog" code.
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
> Instead, the standard leaves the whole thing as a quality of
> implementation issue. The behavior is undefined, meaning that a
> compiler can report warnings or errors for cases when it can
> determine that a reference to an auto object will be returned.
> A good compiler will do so for cases like the first example.
Apparently there aren't a lot of good compilers.
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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: No Author
Date: No Date Raw View
// Test code:
#include <iostream>
struct S1 {
void* operator new(size_t size)
{
std::cout << "S1::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void operator delete(void* p)
{
std::cout << "S1::operator delete(void*)" << std::endl;
free(p);
}
int i;
};
struct S2 {
S2()
{
throw 0;
}
void* operator new(size_t size)
{
std::cout << "S2::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void operator delete(void* p)
{
std::cout << "S2::operator delete(void*)" << std::endl;
free(p);
}
int i;
};
struct S3 {
void* operator new(size_t size)
{
std::cout << "S3::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void operator delete(void* p, size_t n)
{
std::cout << "S3::operator delete(void*, size_t n = " << n << ")" <<
std::endl;
free(p);
}
int i;
};
struct S4 {
S4()
{
throw 0;
}
void* operator new(size_t size)
{
std::cout << "S4::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void operator delete(void* p, size_t n)
{
std::cout << "S4::operator delete(void*, size_t n = " << n << ")" <<
std::endl;
free(p);
}
int i;
};
struct S5 {
void* operator new(size_t size, size_t n)
{
std::cout << "S5::operator new(size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
return malloc(size);
}
void operator delete(void* p, size_t n)
{
std::cout << "S5::operator delete(void*, size_t n = " << n << ")" <<
std::endl;
free(p);
}
int i;
};
struct S6 {
S6()
{
throw 0;
}
void* operator new(size_t size, size_t n)
{
std::cout << "S6::operator new(size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
return malloc(size);
}
void operator delete(void* p, size_t n)
{
std::cout << "S6::operator delete(void*, size_t n = " << n << ")" <<
std::endl;
free(p);
}
int i;
};
struct S7 {
void* operator new(size_t size)
{
std::cout << "S7::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void* operator new(size_t size, size_t n)
{
std::cout << "S7::operator new(size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
return malloc(size);
}
void operator delete(void* p, size_t size)
{
std::cout << "S7::operator delete(void*, size_t size = " << size <<
")" << std::endl;
free(p);
}
void operator delete(void* p, size_t size, size_t n)
{
std::cout << "S7::operator delete(void*, size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
}
int i;
};
struct S8 {
S8()
{
throw 0;
}
void* operator new(size_t size)
{
std::cout << "S8::operator new(size_t size = " << size << ")" <<
std::endl;
return malloc(size);
}
void* operator new(size_t size, size_t n)
{
std::cout << "S8::operator new(size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
return malloc(size);
}
void operator delete(void* p, size_t size)
{
std::cout << "S8::operator delete(void*, size_t size = " << size <<
")" << std::endl;
free(p);
}
void operator delete(void* p, size_t size, size_t n)
{
std::cout << "S8::operator delete(void*, size_t size = " << size
<< ", size_t n = " << n << ")" << std::endl;
}
int i;
};
int main()
{
S1* ps1 = new S1;
delete ps1;
try {
S2* ps2 = new S2;
}
catch(...) {
}
S3* ps3 = new S3;
delete ps3;
try {
S4* ps4 = new S4;
}
catch(...) {
}
S5* ps5 = new(0) S5;
delete ps5;
try {
S6* ps6 = new(0) S6;
}
catch(...) {
}
S7* ps7a = new S7;
delete ps7a;
S7* ps7b = new(0) S7;
delete ps7b;
try {
S8* ps8a = new S8;
}
catch(...) {
}
try {
S8* ps8b = new(0) S8;
}
catch(...) {
}
return 0;
}
/* Output:
S1::operator new(size_t size = 4)
S1::operator delete(void*)
S2::operator new(size_t size = 4)
S2::operator delete(void*)
S3::operator new(size_t size = 4)
S3::operator delete(void*, size_t n = 4)
S4::operator new(size_t size = 4)
S5::operator new(size_t size = 4, size_t n = 0)
S5::operator delete(void*, size_t n = 4)
S6::operator new(size_t size = 4, size_t n = 0)
S6::operator delete(void*, size_t n = 0)
S7::operator new(size_t size = 4)
S7::operator delete(void*, size_t size = 4)
S7::operator new(size_t size = 4, size_t n = 0)
S7::operator delete(void*, size_t size = 4)
S8::operator new(size_t size = 4)
S8::operator new(size_t size = 4, size_t n = 0)
S8::operator delete(void*, size_t size = 0)
*/
[ 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: No Author
Date: No Date Raw View
Tony
---
[ 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: No Author
Date: No Date Raw View
> I have looked through implementations of several std c++ libraries
> (Microsoft VC++, g++, EGCS, Metrowerks CW) and they all do the same thing:
> typedef pointer to iterator. Unfortunately I could not find a place in the
> standard wich states that this is the right or wrong way of doing that.
Let's use Microsoft C++ as an example, because I happen to have it
handy.
vector<int> vec;
Because of default template parameters rarely specified, this is
actually equivalent to "vector<int,allocator<int> >"
vector<int>::iterator i;
Inside vector<>, iterator is typedef'ed to allocator::pointer.
allocator<> typedef's pointer to _Ty*, so in this case it is an
int*.
vector<int>::reverse_iterator j;
Inside vector<>, reverse_iterator is typedef'ed to reverse_iterator
<iterator, value_type, reference, _Tptr, difference_type>
where reverse_iterator<> is a template class that constructs a
reverse iterator for any bidirectional iterator. The template
contains any iterator type (even another reverse_iterator!), so
at some level it ends up containing a pointer (or another iterator,
which contains either a pointer or yet another iterator, and so on).
However, containing a pointer and being a pointer are quite
different things, even if sizeof(iterator)==sizeof(int*).
> Please help.
It sounds like you're trying to do something which, even if it does
turn out to be portable between compilers, will put severe limits on
the type of iterators it can be used with. You can avoid this limit
if you take care *NOT* to assume that an iterator is (or is not) a
pointer.
----
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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: No Author
Date: No Date Raw View
I think most people reading this newsgroup are likely to agree that
standardization is a good idea, but there needs to be a barrier
preventing it from being misused. For example, consider what a
Microsoft-dominated committee would have done. In the opposite
direction, consider how Microsoft feels about Sun's sponsorship of the
work on a Java 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: No Author
Date: No Date Raw View
namespace std {
template <class T, class Allocator = allocator<T> >
class vector {
public:
// types:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef implementation defined iterator; // See _lib.container.requirements_
typedef implementation defined const_iterator; // See _lib.container.requirements_
Unless this has changed in the final standard (which I don't have
access to), the standard doesn't mandate pointers. It doesn't
forbid them eiter, though.
The following is a quote from the design document of the
EGCS Standard C++ library v3:
Replacing the vector iterators, which currently are simple element
pointers, with class objects would greatly increase the safety of the
client interface, and also permit a "debug" mode in which range,
ownership, and validity are rigorously checked. The current use of
pointers for iterators is evil.
It's a strong hint that even for real compilers, you will
not be able to depend on vector iterators being 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: No Author
Date: No Date Raw View
-petter.
--
[- http://matfys.lth.se/~petter/ -]
[ 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: No Author
Date: No Date Raw View
> Perl has garbage collection (of some sort).
Yeah, I often hear that statement, but I disagree with it. Perl has autom=
atic memory=20
management all right, but I'm reluctant to call it 'garbage collection' s=
imply=20
because...not garbage is ever created! In Perl an object is destroyed *as=
*soon*as* it's=20
no longer needed (in the absence of cycles of course <g>).
> As I indicated earlier in the thread, I tend to prefer interface=20
> objects to closures (or to functors). You can do a lot more with
> them--at any rate, if you create an interface object with a single
> method called "doit()", essetially you got yourself a closure. The
> only difference is the syntax-- closure.doit() rather than closure().
> =20
> Not a big difference.=20
Granted. OTOH creating classes when a closure would do *feels* wrong to m=
e.
Introducing a class in a system is a *big* event. A class should model bu=
siness concepts,=20
or user interface concepts, well, *concepts* at any rate. Plus, later som=
eone may come=20
maintain your program and she will need to understand its class structure.
In my book classes are not mere coding tricks. Closures do rank lower tho=
ugh...
I've had the experience of implementing an object-to-relational mapper in=
both Perl and=20
C++. Much of the layer consists of traversing data structures, especially=
DAGs (the=20
class inheritance graph, of course). It also uses defered actions to hand=
le cyclic=20
structures.
The Perl version makes extensive use of closures, the C++ version uses fu=
nction objects,=20
visitors and the like. Often I would find it very difficult to find sensi=
ble names for=20
the C++ classes that were anonymous in Perl.
The C++ version weights 12,500 lines; Perl: 3500.
Of course closures all by themselves don't account for the difference...
> Now if inner classes (or something similar) were added to C++...I'd
> be happy. ;)
Have you ever looked at Beta? It uses a single mechanism (the pattern) to=
represent=20
classes, functions, methods, inner classes, singletons, closures, generic=
s and whatever=20
else.
Jean-Louis Leroy
http://ourworld.compuserve.com/homepages/jl_leroy
---
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
----
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
5 References, pointers, and iterators referring to the elements of
a basic_string sequence may be invalidated by the following uses
of that basic_string object:
...
-- Calling non-const member functions, EXCEPT operator [](),
at(), begin(), rbegin(), end(), and rend().
Because of the word EXCEPT here, this actually says that [], at, and
so on do NOT invalidate iterators.
-- Subsequent to any of the above uses except the forms of
insert() and erase() which return iterators, the first call
to non-const member functions operator[](), at(), begin(),
rbegin(), end(), rend().
I interpret "Subsequent to any of the above uses" to mean "After one
of these uses which we already said may invalidate pointers/iterators."
So what this seems to mean is that after we invalidate iterators any
other way (except for insert() and erase()), the next time we use
[], at, and so on we invalidate them AGAIN. Which seems pointless.
6 [Note: These rules are formulated to allow, but not require, a
reference-counted implementation. A reference counted
implementation must have the same semantics as a non-reference
counted implementation. [Example:
string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = 'a'; // Must modify only s1
--end example] --end note]
> What is the guiding philosophy here? Use copy-on-write implementations only
> in non-multithreaded environments?
I don't think that was the intent, but I do believe that is the
result.
If you haven't already done so, be sure to check out
http://www.sgi.com/Technology/STL/string_discussion.html
for a discussion about why they didn't implement reference counting
on strings. The discussion was written long ago, before the standard
was approved, but it still seems valid today. Note that their
discussion assumes multiple threads; there is nothing presented which
would prevent reference-counted strings in single-thread environments.
The discussion doesn't go far enough, however -- they don't give
any proposed rules which would have solved the dilemma. But it
may be impossible to create reference-counted strings and still
provide the tools that C programmers expect.
What if basic_string was not considered a sequence? We could have
had a basic_string without operator[], begin(), end(), et. al.
at()const would still exist, returning a character by value. There
would be no way to get a pointer or iterator or reference to the
internal data. This needn't be a loss of functionality; we could
add member functions like left(n), right(n), mid(a,b), and so on
to create new strings from portions of the old strings. We could
add member functions like replace(n,char) and delete(n,char,count=1)
and insert(n,char) and insert(n,basic_string&) to manipulate the
existing string.
Such a class would solve most (not all) of the problems that are
currently being solved by basic_string. But it wouldn't conform
to what C/C++ programmers think of as a string, so I guess it is
doomed.
----
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
So a compiler could do runtime array bounds checking, at least when
you compile in debugging mode. This completely eliminates the need
for the at() function. Besides, changing commands like "s.at(n)"
to "s[N]" is very tedious, so rather the compiler do it automatically.
I think that GHS does runtime arrays bound checking for builtin
arrays when you compile in debug mode.
Furthermore, if the compiler can detect an out of bounds violation
at compile time, it can issue a warning, or possibly even an error.
This runtime checking might be difficult for the implementor to
implement, but it's possible, within the standard, and invaluable
to language users.
--
----------------------------------
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: No Author
Date: No Date Raw View
For an enumeration where emin is the smallest enumerator and emax is the
largest, the values of the enumeration are the values of the underlying
type in the range bmin to bmax, where bmin and bmax are, respectively, the
smallest and largest values of the smallest bit-field that can store emin
and emax.
[Footnote: On a two's-complement machine, bmax is the smallest value
greater than or equal to max ( abs ( emin ) - 1, abs( emax )) of
the form 2M - 1; bmin is zero if emin is non-negative and -( bmax + 1 )
otherwise. --- end foonote]
And from section 9.6 paragraph 4:
If the value of an enumerator is stored into a bit-field of the same
enumeration type and the number of bits in the bit-field is large enough to
hold all the values of that enumeration type, the original enumerator value
and the value of the bit-field shall compare equal.
Since there are no negative enumerator values in "E", the values of "E" can
be stored in two bits. In practice the implementation must treat the
representation as unsigned, but this is an implementation detail only.
-- 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
If I'm right, I see a further interesting conclusion:
If the compiler wants to take full advantage of URVO, it must
allow the second optimisation, even if it doesn't see the
function source (i.e. the function is not inline).
This means that the NRVO cannot be used for non-inline
functions, since the compiler must expect the return value
being optimized out at the caller side (which would not
be legal after NRVO). And this means that NRVO isn't quite
as useful as one may think.
However, if I'm wrong, then NRVO seems indeed dangerous for such
cases. Maybe it would be better to restrict NRVO to non-POD types
(optimisation of POD types can usually be done under the as-if
rule anyway). Or to describe the effect not as just allowing
the optimisation, but as "optimising as if the copy constructor
and destructor had no side effects". That is, the existance of
copy constructor and destructor (with possible side effects)
doesn't limit the optimisations, but the only optimisations
allowed are those which don't violate the as-if rule otherwise
(that is, not via copy constructor/destructor).
---
[ 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: No Author
Date: No Date Raw View
Why not explain this on comp.lang.c++. It sounds interesting, but
I don't quite understand it.
--
----------------------------------
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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
--
Faisal Vali fvali@biotrack.com
Software Engineer Identix Biometric Security
WWW: http://www.identix.com
-------------------------------------------------------
This triviality made him think of collecting many such moments together
in a book of epiphanies. By epiphany - a sudden spiritual manifestation,
whether in the vulgarity of speech or gesture, or in a memorable phrase
of the mind itself. He believed that it was for the man of letters to
record these epiphanies with extreme care, seeing that they themselves
are the most delicate and evanescent of moments. (James Joyce)
---
[ 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: No Author
Date: No Date Raw View
The above quote leaves out the first sentence, and this
sentence suggests that the optimization apply just as
well to the unnamed case. Here's the full paragraph,
from 12.8 "Copying class objects", item 15, where I've
split each sentence into its own paragraph:
(i) Whenever a temporary class object is copied
using a copy constructor, and this object and the
copy have the same cv-unqualified type, an
implementation is free to treat the original and
the copy as two different ways of referring to
the same object and not perform a copy at all,
even if the class copy constructor or destructor
have side effects.
(ii) For a function with a class return type, if
the expresssion in the return statement is the
name of a local object, and the cv-unqualified
type of the local object is the same as the
function return value, an implementation is
permitted to omit creating the temporary object
to hold the function return value, even if the
class copy constructor or destructor has side
effects.
(iii) In these cases, the object is destroyed at
the later of times when the original and the copy
would have been destroyed without the
optimization.
Author: No Author
Date: No Date Raw View
Sentence (ii) is a repeat of (i) for the special
case of named locals. It used to be the case that
the optimization could only apply to unnamed
locals, or temporaries as some prefer to call it.
But as they extended the rule to named locals, I
guess they figured they should add a sentence to
spell it out in full. (Or at least this is my
guess about the history of this paragraph.)
I'm somewhat confused about this business of
cv-unqualified types. Are they saying that if
the local object has type "T" and the return has
type "const T", that the return value
optimization can't be applied? Eg,
const T read(std::istream& input) {
T out;
input >> out;
return out; // copy required?
}
It is reasonable to return const values. For
builtin types, const return values don't mean
a thing. But for user types, const return
values do mean something. They prevent users
from accidentally calling const member
functions on the returned temporary. In short,
const return values are useful, and it would
be nice if the return value optimization
applied to them. So, what's the deal here?
Why can't the return value optimization be
applied here? Or do top level consts not
figure into the definition of cv-unqualified?
As for pointer types, who cares whether the
return value optimization is applied? After
all, copying a pointer is so cheap anyway.
Eg,
T const * f() {
T * out=0;
return const_cast<T const*>(out); // copy required?
}
As 'out' and the return value don't have the same
cv qualified type, a call to the copy constructor
is forced. But we're copying pointers anyway, and
the copy is inexpensive. But if pointers of type
"T *" and type "T const *" have the same
representation, I don't see why the compiler apply
the return value optimization. Eg, suppose that
sizeof(T*)==sizeof(T const *)==4. Then the variable
'out' could be created directly in the return
space. IOW, the optimization should still apply.
>I may well be out of date here, but it certainly seems
>like the unnamed case would be easier to
>implement than the named case. I can't see why
>you would permit the named and not the unnamed.
>Please correct this impression if it's wrong.
Yes, the unnamed case is easier to implement as the
compiler doesn't have to track variables. Egcs
already does the return value optimization for unnamed
locals. I'm sure most do.
--
----------------------------------
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: No Author
Date: No Date Raw View
>David:
>> Except that it forces one to arrange the members of a class with
>> regard to initialization sequence, rather than with regard to
>> structure packing considerations (i.e., memory space optimization).
>> This can have a detrimental effect on the size of some classes,
>> especially if they contain members of widely mixed sizes.
>Siemel:
>> No. We can precede each data element with the "private" keyword
>> (although I quite like the "private: private:" idea somewhat).
>> Most compilers don't seem to take advantage of this, though.
>This does not give the programmer any more control over member
>ordering than not specifying 'private:'. And how does this help
>with non-private members?
I might misunderstand you here. But in a struct or class, members
in different access specifiers can be rearranged. For example, in
struct X { public: int a,b,c,d };
the layoutof the data members is a,b,c,d. Just one layout.
But in this here:
struct X { public: int a,b; public: c,d };
there are two possible orders. Either a,b,c,d or c,d,a,b.
Ideally the optimizer selects whichever layout minimizes the
size of X. And finally, in
struct X { public: int a; public: int b; public: int c; public: int d; };
there are facorial(4)==24 different possible orders. These are
a,b,c,d ... b,c,a,d ...
Note that in all the above cases, the conceptual order of the objects
is always a,b,c,d. The constructor will initialize in that order,
and de-initialize in the reverse order. But due to the redundant
access specifiers, there may be any of 1, 2, or 24 layouts.
By preceding each variable with a redundant access specifier, we
give the compiler full license in rearranging the struct. I now
see one problem with this: There are just too many possible
layouts. For n data members, there are factorial(n) possible
layouts, and it's going to be tough for the compiler to figure
out which one gives the smallest sizeof. It can be done exactly
for small n, and approximately for large n.
>Unless, of course, the programmer wants to control the layout
>ordering or destruction order of the members for reasons that the
>compiler cannot possibly know. This he cannot do today.
If you want to control the construct/destruct order but not worry
about the layout, then just do the usual: declare the data members
in order and precede each block with a redundant access specifier;
the compiler will choose the best layout.
If you want to control the construct/destruct order as well as
the layout, then your idea seems like the only way to go.
If you don't care about the construct/destruct order but do
care about the layout, then the method in the above paragraph that
is 4 lines long should be ok, although it is overkill.
--
----------------------------------
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: No Author
Date: No Date Raw View
void f() { }
void* pv = reinterpret_cast<void*>( /*(& optional)*/ f );
pv = (void*) /*(& optional)*/ f;
Yet MSVC 6.0 compiles similar conversions.
Is the compiler at fault or am I not interpreting the sections properly
or is there a section that allows such a conversion that I have skipped?
or yet are these conversions well-formed but simply undefined? If so,
what in the standard validates this conclusion.
Thanks a lot,
-fais
P.S And, if you have, thanks for all your previous help too :-)
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
1. "x || y || z" is always treated as "(x || y) || z" due to
assocativity. (Precedence doesn't factor in, contrary to the subject,
since the two operators are the same.)
2. operator|| defines a "sequence point" such that stuff needed to form
the left operand is always done before stuff needed to form the right
operand (operator&& and operator, do this too).
3. x is always evaluated before y (if y is evaluated at all, see later points).
4. If the first operator|| is the built-in one, x is evaluated and
"bool(x)" is found (if x wasn't already a bool). Then if "bool(x)" is
"true", "true" is returned without ever evaluating y. If "bool(x)" is
"false" instead, y is evaluated and "bool(y)" is found (if y wasn't
already a bool). If both x and y were evalutated, then the expected
result of "bool(x)" OR'd with "bool(y)" is returned.
5. If the first operator|| is an user-defined one, x is evaluated and
possibly converted to a compatible type, then y is evaluated and possibly
converted to a compatible type, then operator|| is applied.
6. Let's call the result from [4] or [5] Temp1. Note that Temp1 must be a
bool if the built-in operator|| was used, but may be anything if an
user-defined operator|| was used.
7. Point [3] using the second operator||, replace 'x' with 'Temp1' (which
is "x || y") and 'y' with 'z'.
8. Point [4] using the second operator||, replace 'x' with 'Temp1' and 'y'
with 'z'.
9. Point [5] using the second operator||, replace 'x' with 'Temp1' and 'y'
with 'z'.
10. Point [6], replacing points [4] and [5] with [8] and [9], and
replacing 'Temp1' with 'Temp2'.
11. Temp2 is what is returned as the result of the entire expression.
If it is going to be used in an if-statement, like David's example, then
it may have to be converted to bool before continuing.
--
Daryle Walker
Video Game, Mac, and Internet Junkie
walke751 AT concentric DOT net
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Anyone know which rule is correct?
Similar remarks hold for operator&&.
Generally the best decision is not to overload these operators.
>During the same walk-thru it came up that one should not all the
>classes' assignment operator from the copy constructor (i.e. copy
>constructor of *this = sourceObject). Is there any validy to this?
It is legal to do this. To start a discussion about whether it
is good idea to do this, post this same question on
comp.lang.c++.moderated. I think it will be an interesting
discussion.
--
----------------------------------
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: No Author
Date: No Date Raw View
s = s
first do the copy, then destroy the current object
or do the copy inplace
--
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: No Author
Date: No Date Raw View
1. They are treated like static inline functions, and are generated in
place for each source file. This avoids having to look up the function
definition in another file, or waiting until link time to find the
definition. However, you end up with the drawbacks of inline functions.
First, redundant code is generated for the same template, or the compiler
must somehow filter out the redundant code. Second, either the compiler
must do extra work to make sure all definitions of the template are the
same, or fail to warn about violations of the one-definition rule. Last,
the source for the definition must be made available to users.
2. They are extern functions, and have only one definition in one source
file, period. That avoids the problems of inline functions, but forces the
compiler/linker to have to look up definitions across source files.
Having an "export" keyword allows you to choose how you want your template
definition treated. Without the "export" keyword, your template definition
is essentially treated as "inline". With it, your template is treated as
"extern".
[ 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: No Author
Date: No Date Raw View
"An implementation shall not predefine the main function. This
function shall not be overloaded. It shall have a return type of type
int, but otherwise its type is implementation-defined."
------------ Matti Rintala ----------- bitti@cs.tut.fi ------------
"Your reality, sir, is lies and balderdash and I'm delighted to say
that I have no grasp of it whatsoever."
(Baron von M nchausen in "The Adventures of Baron von M nchausen")
[ 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: No Author
Date: No Date Raw View
3.6.1 Main function [basic.start.main]
1 A program shall contain a global function called main, which is the
designated start of the program. ...
2 An implementation shall not predefine the main function. This
function shall not be overloaded. It shall have a return type of
int, but otherwise it's type is implementation-defined. All
implementations shall allow both of the following definitions of
main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In the latter form argc shall be the number of arguments passed
to the program from the environment in which the program is run.
If argc is nonzero these arguments shall be supplied in argv[0]
through argv[argc-1] as pointers to the initial characters of
null-terminated multibyte strings (NTMBSs) (17.3.2.1.3.2) and
argv[0] shall be the pointer to the initial character of an
NTMBS that represents the name used to invoke the program or "".
The value of argc shall be nonnegative. The value of argv[argc]
shall be 0. [Note: it is recommended that any further (optional)
parameters be added after argv.]
...
5 A return statement in main has the effect of leaving the main
function (destroying any objects with automatic storage duration)
and calling exit with the return value as the argument. If control
reaches the end of main without encountering a return statement,
the effect is that of executing
return 0;
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
shall v. aux. Makes compound tenses or moods to express obligation,
command, condition or intention (should p.t.)
synonym n. Word with same meaning as another.
I'd say must is a synonym to shall.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
"Program Startup: the main Function
A special function called main is the entry point to all C++
programs...Alternatively, the main and wmain functions can be declared as
returning void (no return value). If you declare main or wmain as returning
void, you cannot return an exit code to the parent process or operating
system using a return statement; to return an exit code when main or wmain
are declared as void, you must use the exit function."
Regards,
Vlad
[ 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: No Author
Date: No Date Raw View
That's somewhat vague, I suppose.
--
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: No Author
Date: No Date Raw View
"Except as noted in clauses 18 through 27, the contents of each header
/cname/ shall be the same as that of the corresponding header /name/.h,
as specified in [the ISO C standard], as appropriate, as if by inclusion.
In the C++ Standard Library, however, the declarations and definitions
(except for names which are defined as macros in C) are within namespace
scope (3.3.5) of the namespace std."
As I read that, the names (other than macros) declared in <cmath> should
go in namespace std, and a compiler that puts them in the global
namespace is wrong.
There's a reference a couple of paragraphs later to D5 for the headers
*.h.
D.5 says, in paragraph 2: "Each C header, whose name has the form
/name/.h, behaves as if each name placed in the Standard library
namespace by the corresponding /cname/ header is also placed within the
namespace scope of the namespace std and is followed by an explicit
/using-declaration/ (7.3.3)".
And paragraph 3 gives an example that is hard to misinterpret:
"[/Example:/ The header <cstdlib> provides its declarations and
definitions within the namespace std. The header <stdlib.h> makes these
available in the global name space, much as in the C Standard. --/end
example/]" (square brackets in original)
--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
http://www.concentric.net/%7eBrownsta/
"I'm not even supposed to BE here!" -- the mantra from /Clerks/
My reply address is correct as is. The courtesy of providing a correct
reply address is more important to me than time spent deleting spam.
[ 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: No Author
Date: No Date Raw View
This only applies to <c*> headers, such as <cmath>. If you #include
<math.h>, the names should be defined both in the global namespace and
in namespace std, per appendix D.5.
[ 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: No Author
Date: No Date Raw View
I'm not going to comment on this. All I know is I wouldn't want to write
the
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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
Cristian Georgescu
_________________________________________________
email: CGeorges@lehman.com
tel: (212) 526-3502
_/ _/_/_/_/ Lehman Brothers
_/ _/ _/ Equity Finance Systems
_/ _/_/_/_/ World Financial Center
_/ _/ _/ 200 Vesey Street
_/_/_/ _/_/_/_/ New York, NY 10285.
_________________________________________________
[ 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: No Author
Date: No Date Raw View
I think these are clear benefits of an override keyword. I would not
expect implementation to be very difficult. I'm not sure how to measure
the cost of increasing the complexity of the language by adding a new
keyword against the benefits of the new keyword. At the very least I
think it merits discussion when the next revision of the language is
considered.
--
Kirk Swenson
Senior Software Engineer
Key Curriculum Press
kswenson@keypress.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: No Author
Date: No Date Raw View
1.1 Scope [intro.scope]
[...]
5 Although this International Standard states *only* requirements on
C++
*implementations*, those requirements are often easier to understand
if
they are phrased as requirements on programs, parts of programs, or
execution of programs. Such requirements have the following meaning:
--Whenever this International Standard places a diagnosable require-
ment on the form of a program (that is, the characters, tokens, syn-
tactic elements, and types that make up the program), and a program
does not meet that requirement, the program is ill-formed and the
implementation shall issue a diagnostic message when processing that
program.
--Whenever this International Standard places a requirement on the
execution of a program (that is, the values of data that are used as
part of program execution) and the data encountered during execution
do not meet that requirement, the behavior of the program is unde-
fined and this International Standard places no requirements at all
on the behavior of the program.
>
> Consider:
>
> int i[1];
> int j[1];
> int k[1];
>
> By your logic, i+1==j and j+1==k are strictly conforming, but i+1==k is
> not.
All of them are strictly conforming, i.e. a strictly conforming
implementation is required to accept this code, and to give a return
value of either true or false.
The question is, if a conforming implementation may return true for
any of those, or if it is required to return false for every of
the three.
If the latter, most if not all current implementations are broken
in this respect, since it's common to return true for i+1==j and
j+1==k (it's also possible that some implementation has k+1==j and
j+1==i, if the variables are allocated in order on a downward-growing
stack). Or the other way round, the standard is broken, because
it needlessly causes the usual implementation to be broken.
> But as far as everything in the language specification is concerned,
> they're semantically identical. It makes no sense for their conformance
> levels to be different -- either they're all strictly conforming or none
> are. Where in the specification does it ever suggest that the memory
> layout should be ijk rather than kji or ikj?
Nowhere. But some are reading it as "all those are broken, the
memory layout must be like i_j_k, k_j_i, i_k_j or similar", where
_ denotes padding.
---
[ 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: No Author
Date: No Date Raw View
> > ie. the following, if stuck in a class, will not compile...
> >
> > virtual void Display() const = 0
> > {
> > // NOT ON!
> > cout << "In: virtual void Display() const = 0..." << endl;
> > }
> >
> > Is this correct?
>
> I thought this was illegal behaviour. In 10.4/2 of the standard, there
> is a note, saying:
>
> "A function declaration cannot provide both a pure specifier and a
> definition".
>
> So, according to that, the above definition will be illegal.
This means that you can't declare a member function as pure virtual
and implement it at the same time, as Biju points out later in the
post. But you most certainly CAN implement pure virtual functions,
as I've stated above.
However, if you can do the equivalent anyway, why can't you do them
both in the declaration? This seems counter to the C++ way of doing
things. And the syntax seems obvious, exactly what Callanans posted
above. After all, if const is given at the same time as the function
body, that's where the const keyword would go, right?
So I looked at the note that Biju cited. It is a note, which means
that it is "non-normative," but it also talks about exactly this one
small topic, and it even gives an example:
For example,
struct C {
virtual void f() { }=0; // ill-formed
};
--end note]
But look at the example a bit closer. Where is that pure-virtual
specifier? It's AFTER the function body!
FWIW, I tried this with VC++5 and got
error C2059: syntax error : '='
while Callanans' example compiled with nary a peep. So Microsoft
did comply with the example in the non-normative note.
> I also checked in the grammar provided in Stroustrup, C++PL, 3rd ed. I
> could not figure out a way by which the above code will be legal.
I looked in the ARM, on p215. There are no examples of declaring
a function pure virtual and defining it at the same time. There
is an example of explicitly calling a pure virtual function:
Note that a pure virtual can be defined. It can be called using
explicit qualification only, as follows:
class A {
virtual void f() = 0;
A() {
A::f(); // ok
}
};
void A::f() // defined somewhere
{
// ...
}
> But, mysteriously, VC++ accepted this code.
> Can someone clarify whether this is legal or not?
I certainly hope so, the counter-example notwithstanding...
> OTOH, the following should be legal:
>
> class Shape
> {
> virtual void Display () const = 0;
> };
>
> void Shape::Display () const
> {
> cout << "In: virtual void Display() const = 0..." << endl;
> }
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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: No Author
Date: No Date Raw View
int j; // Or whatever type
...
typeof (j) k; // Declare variable which is of the same type as 'k'.
As far as the compiler has knowledge about each object's type, it looks to
me that it is perfectly implementable.
What are the advantages of such keyword?
1.You can write macros that are safer or simpler. E.G.
#define SWAP(a,b) { typeof (a) temp = a; a = b; b = temp; }
(I know this can be done with templates. Did I mentioned 'C'?
No templates there. And it was just an example, anyway.)
2.The code might be both simpler to write and maintain. There are cases
in which the types of some things MUST be the same. E.G.:
int a; // or whatever type
...
int b, c, d, e, f; // Actually assumig 'same type as 'a's one)
....
Imagine that you have to change all from int to long. You have to change all
declarations, instead of one, provided that the code looked this way:
int a; // Or whatever type
...
typeof (a) b, d, e, f;
(Again: I know that you might have 'typedef int T;' in which case you will
only change the typedef. On the other hand, I read somewhere at least one
sugestion to restrict usage of typedefs (which looks very stupid to me,
but this is just another story)).
I know that template functions and classes solve such problems at big extend,
as far as you can refer to the template's argument (if it was a type). And
there are always workarounds (as shown above). Anyway, the presense of
'typeof' would be just another possibility: I personally would use it.
When 'typeid' emerged, I hoped that there would be something similar to my
idea there. Unfortunatelly, there isn't.
-------------------------
I tried (unsuccessfuly) to achieve the desired effect, using 'standard'
means. Here is the result:
template <class T>
struct TypeInfo
{
typedef T TypeOf;
TypeInfo (T) {};
};
template <class T>
TypeInfo<T> getTypeInfo (T t)
{
return TypeInfo (t);
}
#define typeinfo(x) getTypeInfo(x)::TypeOf
typeinfo(4) j; // intedning declaring int j. Will it work?
...NOPE. Classes can be used in this way, but objects cannot, although
(again!) I can't see why.
======================
I await any comments and ideas. And, if any of you can influence the
future of the language (can't we all?), PLEASE consider my proposal as well...
Radoslav Getov
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: No Author
Date: No Date Raw View
DDJ: Set, multiset, map, and multimap are implemented with a red-black-tree
data structure. Have you experimented with other structures such as B*trees?
AS: I don't think that would be quite right for in-memory data structures,
but this is something that needs to be done. The same interfaces defined by
STL need to be implemented with other data structures--skip lists, splay
trees, half-balanced trees, and so on. It's a major research activity that
needs to be done because STL provides us with a framework where we can
compare the performance of these structures. The interface is fixed. The
basic complexity requirements are fixed. Now we can have meaningful
experiments comparing different data structures to each other. There were a
lot of people from the data-structure community coming up with all kinds of
data structures for that kind of interface. I hope that they would implement
them as generic data structures within the STL framework.
---
[ 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: No Author
Date: No Date Raw View
[ 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: No Author
Date: No Date Raw View
--
// 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: No Author
Date: No Date Raw View
2 An expression is potentially evaluated unless either it is the
operand of the sizeof operator, or it is the operand of the typeid
operator and does not designate an lvalue of polymorphic class
type.
Author: No Author
Date: No Date Raw View
2 When typeid is applied to an lvalue expression whose type is a
polymorphic class type, the result refers to a type_info object
representing the type of the most derived object (that is, the
dynamic type) to which the lvalue refers. If the lvalue
expression is obtained by applying the unary * operator to a
pointer and the pointer is a null value, the typeid expression
throws the bad_typeid exception.
3 When typeid is applied to an expression other than an lvalue of
a polymorphic class type, the result refers to a type_info
object representing the static type of the expression. Lvalue
to rvalue, array to pointer, and function to pointer, conversions
are not applied to the expression. If the type of the expression
is a class type, the class shall be completely defined. The
expression is not evaluated.
Since class int is not a polymorphic type -- it has no virtual
pointer, no virtual functions -- rule #3 applies. Therefore,
the typeid expression resolves into typeid(int).
If you did typeid(*null<T>()), then if T is not a polymorphic type,
the result is the same as typeid(T). If T is a polymorphic type, the
result is a the bad_typeid exception.
>1. this is a null-pointer dereference, and thus undefined behaviour.
The arg of typeid is not evaluated.
>2. this is an expression of the structure *(T*)0, and should therefore
> throw std::bad_typeid.
Only if T is a polymorphic type.
>3. the expression has a static type int, and should therefore return
> a reference to typeid(int).
Seems correct to me. Incidentally, this is what egcs and como do.
-----
#include <typeinfo.h>
#include <iostream>
template <class T>
inline T* null() { return (T*)0; }
struct StaticType { };
struct PolymorphicType { virtual ~PolymorphicType() { } };
int main()
{
try
{
cout << typeid(*null<StaticType >()).name() << '\n';
cout << typeid(*null<PolymorphicType>()).name() << '\n';
}
catch (std::bad_typeid e) { cout << typeid(e).name() << '\n'; }
}
On como, the output is
StaticType
std::bad_typeid
On egcs, replace <typeinfo.h> with <typeinfo>, which incidentally is
the correct thing, and the output is
10StaticType
Segmentation fault (core dumped)
It's correct that the second typeid should fail, but it is not correct
that the exception go uncaught.
--
----------------------------------
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: No Author
Date: No Date Raw View
(That sentence refers to the parameter itself, of course, as in
the example above. If you write "const char* p;", p is not const,
and the const is therefore significant.)
--
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: No Author
Date: No Date Raw View
o Has no constructors.
o Has no nonpublic members.
o Has no base classes.
o Has no virtual functions.
Given the above definition, one should be able to initialize the type using
list initialization.
Now, I have the following:
class Ca
{
public:
Ca( int x );
Ca( const Ca & );
...
};
struct Sa
{
Ca m_a;
};
I believe that Sa is an aggregate given the above definition. As a result,
I should be able to do the following:
Sa sa =
{
Ca( 10 )
};
The MS compilers (5.0 and 6.0) are rejecting 'sa' saying that it's not an
aggregate. First line tech. support at MS is saying that Ca having a
constructor makes Sa a non-aggregate structure.
Can someone settle this (a sighting in the standard would be helpful)?
Thanks.
---
[ 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: No Author
Date: No Date Raw View
[ 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: No Author
Date: No Date Raw View
--
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: No Author
Date: No Date Raw View
[using "void func(vector<T>&)" for LINE2]
>Negative. "g++ -Wall -o overload overload.cxx" compiles your code
>without any warning, but the resulting program prints
>
> Function version A // LINE1
> Function version A // LINE2
> Function version C // LINE3
>
>on invocation. The version with a "const std::vector<T>" argument gives
>the expected answer "Function version B" when invoked with a vector.
>
>Any idea what's going on?
Yes, LINE2 was called as follows:
func(vector<int>());
The three candidate funcs are
void func(T& x);
void func(vector<T>& x);
void func(double x);
Since 'x' is a temporary, a free function that uses it must receive
it by value or by const reference. So these would be preferred:
void func(const vector<T>& x);
void func(vector<T> x);
This function is never considered for overload resolution:
void func(vector<T>&);
It should be considered for error and warning messages though.
There is a question on comp.lang.c++.moderated about this very same
question. Subject is "auto_ptr ...".
--
----------------------------------
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: No Author
Date: No Date Raw View
> > > I think VC++5.0's STL has the same level of thread-safety if I apply the
> > > fixes sugguested by Mr. Plauger. Correct me if I am wrong. Anybody knows
> > > about VC++6.0?
> >
> > Apply the same fixes and it too is thread safe, in the same sense as SGI.
>
> The entire standard library or only the STL part?
AFAIK, the entire standard library is thread safe, once the fixes are applied.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com/hot_news.html
---
[ 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: No Author
Date: No Date Raw View
4 ... After all replacements due to
macro expansion and the defined unary operator have been performed,
all remaining identifiers are replaced with the pp-number 0, and then
each preprocessing token is converted into a token.
So if _MSC_VER is not defined, this
#if _MSC_VER >= 1000
is converted into this
#if 0 >= 1000
--
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: No Author
Date: No Date Raw View
I agree whole heartedly that math functions should not have side
effects. Certainly, the current ones are problematic in multi-threaded
code.
My suggestion would be as follows. Use three (!) namespaces
The current math functions go into std namespace (I can't recall if
they're in std or not). The intent of this namespace is backward
compatibily with C, and to allow use of code that works now.
A second complete set go into a mathdebug namespace. The functions
in this this namespace simply throw a relevant exception in conditions
where the std ones set errno. These functions would normally be
used for program development, and will be intended for software
as delivered to a user.
A third complete set go into a math namespace. These functions do
not throw exceptions or set errno --- and have an exception
specification
that reflects this. Instead they could simply *assume* their arguments
are valid, and the standard simply mandate that the results for
invalid arguments are undefined.
If I have these choices I would use either std or mathdebug for
development and testing. Once I'm confident that I've caught
everything, a simple using statement could be used to switch
over to the math namespace. If course, I also hope that, given
the specification
void foo() throw();
that a compiler/optimiser can cut out overhead for exception
handling in code like the following.
try
{
foo();
}
catch (anything)
{
// whatever
}
-<Automagically included trailer>
Robert O'Dowd Ph +61 (8) 9553 3618
DSTO Bldg A51 Fax +61 (8) 9553 3577
HMAS Stirling Email:
robert.odowd@dsto.defence.gov.au
Rockingham, Western Australia, 6958
Disclaimer: Opinions above are mine and may be worth what you paid for
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: No Author
Date: No Date Raw View
---------------------------
Matthew Reece
matt.reece@iname.com
swarsmatt@aol.com
---------------------------
-----== 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: No Author
Date: No Date Raw View
Example 1:
ci_string a = "qwerty";
string b;
b = a; // illegal, no string::operator = (ci_string const&);
Example 2:
ci_string a = "qwerty";
cout << ci_string << endl;
/* illegal, no
basic_ostream<char, char_traits>&
operator << (basic_ostream<char, char_traits>&,
basic_string<char, ci_char_traits, Allocator>
const&);
defined. */
In these cases, I think we've carried object-oriented concepts a bit
too far. Objects are good and all, but sometimes we need to focus on
actions instead.
[ 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: No Author
Date: No Date Raw View
Second, you can't always get what you want, not even if you're Microsoft. V6.0
*should* have included much better conformance, particularly for the library, but
for some unfortunate distractions. Click on the link at the bottom of this message
to see what I mean.
I don't pretend to speak for Microsoft, but I do know the attitudes of several of the
key technical people there. I, for one, am pleased that people like these are the
stewards of such an important product as VC++.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com/hot_news.html
[ 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: No Author
Date: No Date Raw View
What's in it ?
--------------
The differents part of the library are:
Promoter
computes type promotion
Checked ints
provides bound checking
The choosers
let you designate integral types by their properties
Extended numerical limits
better numerical_limits class template
The chooser part partially match what you are doing.
--
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: No Author
Date: No Date Raw View
Thanks in advance for any assistance,
--
Chad Gatesman
Software Engineer
[ 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: No Author
Date: No Date Raw View
--
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: No Author
Date: No Date Raw View
1.Is KAI C++ thread-safe?
The code generated by KAI C++ is thread-safe as long as you do not
turn on exceptions. The current versions of KAI C++
are not thread-safe with exceptions enabled.
> BTW as far as I know, the ISO
> standard makes no mention of threads so this does not impact the
> ISO conformance of the compiler.
>
That is no consolation to a programmer using threads.
-- Saroj Mahapatra
-----== 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: No Author
Date: No Date Raw View
> System-depdent libraries? Yes of course, but that's not LANGUAGE
> extensions. Hooks into assembler? On rare occasions, yes, but
> again, it *CAN* be done entirely without LANGUAGE extensions.
> Access to DLLs? Why yes of course, but no sane system has or needs
> any LANGUAGE extensions for that!
About the only point I can seriously agree with is the last.
--
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
[ 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: No Author
Date: No Date Raw View
Then what the discussions in this thread is all about that C++ ought to
be a very good for a complete implementation of a dynamic computer
language, but it is not, and we are discussion the parts that are failing.
>This makes implementing one language using another an interesting
>problem. If both languages share a similar "philosophy" it can be
>easy; implementing a Lisp-like language in Lisp is fun, as is
>implementing a logic language in Prolog. But this doesn't always
>follow: Imagine implementing a simple interpreted OO language in C++;
>since the class definitions of the interpreted language would only be
>seen at run-time, it would not be possible to implement the method
>dispatch mechanism in terms of the method dispatch mechanism of C++.
I can point out that a technique that can be used implementing a
computer language is to make it self-compile: One first makes a simple
version implementation version of the language, and then writes later
versions in terms of the earlier versions. For example, this is how Java
is developed, and also the Glasgow Haskell compiler <http://haskell.org/>.
>I
>think this is the kind of fundamental problem Hans has run into.
The problems discussed are not particularly mine, I think, and as I have
tried to point out: Anyone attempting to use C++ for such a purpose (and
in fact other kinds of applications) will bump into them.
Why does one want to use C++ to implement such a dynamic language?
One reason is that computer scientists implementing various computer
languages has as requirement that the implementations should approach the
efficiency of a computer language like C++. So this gives room for choices
like assembler, C, and C++ as possible choices of languages.
Using assembler is not portable, but I have pointed out Simon
Peyton-Jones <http:/dcs.gla.ac.uk/~simonpj> is developing a portable
assembler called C--.
Why should one then want to use C++? I think it is in fact excellent
because it is on the one hand low level and efficient, but I do not have
to worry about such things as putting temporary variables in registers and
keep track of them in a machine-dependent implementation: Doing that stuff
would take up too much of my time so I would not be able to do any
programming at all, unless I can lend from C++ features as much as
possible. This is also the very idea of C++: A single programmer should be
able to the same stuff as in C, but to avoid the repetitive low level C
programming, and thereby be able to maintain larger amounts of code.
Then there are still some parts of C++ which have been neglected, and we
are discussing two of these topics here: The virtual function pointers (by
now pretty much resolved), and garbage collectors.
I can mention more such features. Adding such features to C++ will make
it possible for more people to implement computer languages, that will
help speed up the computer evolution, and that will benefit everyone.
Hans Aberg * Anti-spam: Remove "REMOVE." from email address.
* Email: Hans Aberg <mailto:haberg@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: No Author
Date: No Date Raw View
Regards.
--
+ Marcus Barnes, Technical Staff mailto:marcus@multigen.com +
+ Multigen Inc. http://www.multigen.com +
+ 550 S. Winchester Blvd. phoneto:1-408-367-2654 +
+ Suite 500 San Jose CA 95128 faxto:1-408-261-4103 +
[ 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: No Author
Date: No Date Raw View
So far, I've only worked on one class where this was a concern. I
wrote a class used to give details to a report generator that
displayed it's results in one of our spreadsheets. I managed to
design the class so that internal changes need never force all the
clients to recompile. Here's a simplified version of what I did:
// The shared headere file
class ReportInternal;
class Report {
ReportInternal *r;
public:
Report();
~Report();
void Function1(int);
int Function2(char);
// etc...
};
And inside the DLL I did this:
class ReportInternal {
// Whatever data is needed.
char data1[];
int data2;
double data3;
// etc...
public:
// These functions do the "real" work.
void Function1(int);
int Function2(char);
// etc...
};
// MAINTENANCE NOTE: DO NOT DELETE ANY FUNCTIONS IN REPORT.
// You may add new functions, but if old ones become obsolete,
// you MUST re-implement them in terms of the new functions.
// Be sure to mark these as *depricated* in the header file
// if appropriate.
Report::Report() : r(new ReportInternal) {}
Report::~Report() { delete r; }
void Report::Function1(int i) { r->Function1(i); }
int Report::Function2(char i) { return r->Function2(i); }
// etc...
I'm not sure what I would have done if I had needed to use any
virtual functions. That could complicate the whole mechanism.
Is there some simpler way to deal with this issue? I'm always
in the market for some new technique to make my life simpler.
(But I don't want to play games with the vtbl, which might or
might not exist!)
-----== 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: No Author
Date: No Date Raw View
* In a template container that's trying to be exception-neutral, it
seems impossible to maintain valid contents if the destructor might
throw an exception while the container is trying to remove an
object. (The STL results are undefined if a destructor throws,
isn't that true?)
* The comments above about auto_ptr show another problem with
destructors throwing.
* Common sense tells us that if an function creates and uses an
object with no exceptions, it ought to be able to exit scope
without exceptions.
* In fact, the only way for a function to catch an exception thrown
by a destructor is to put each such object in it's own try/catch
block. So instead of this:
bool compare_translations(int i, int j) throw(0) {
return NeverThrow(i)==NeverThrow(j);
}
bool compare_translations(int i, int j) throw(0) {
bool result = false;
try {
CouldThrow ii(i);
try {
CouldThrow jj(j);
if (ii==jj) result=true;
} catch(...) {
// Nothing to do, we never throw
}
} catch(...) {
// Nothing to do, we never throw
}
return result;
}
That's the negative side of throwing from a destructor. Is there
any positive side? That is, does throwing from a destructor ever
serve any useful purpose?
Suppose we changed the language to disallow ever throwing from a
destructor. That means that the program couldn't call any throw
functions from the destructor unless it had a try/catch block of
it's own. Would this be A Good Thing(tm)?
If that's too restrictive, we could at least change the default.
For destructors only, the default would be throw(). The programmer
could change this behavior by explicity declaring throws in the
usual way; to indicate that it might throw anything at all, we could
use "throw(...)", as in:
~Object() throw(...) { throwing_func(member_x); }
Realistically, this won't happen, because the current standard was
already approved and because by the time work begins on the next
standard, there will be a substantial body of code that would break.
But does anybody agree with me that it WOULD HAVE BEEN a good idea?
-----== 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: No Author
Date: No Date Raw View
No one's claiming that removing unused virtual functions wouldn't solve
most of the bloat problem. What some people are claiming is that doing
so is very difficult without the use of weak references, and no one has
provided evidence that any implementation that it is close to conforming
with the new standard has actually removed most of the bloat by using
weak references.
---
[ 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: No Author
Date: No Date Raw View
Thus, no undefined behavior, and the results are well defined.
--
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: No Author
Date: No Date Raw View
> >> The standard doesn't say that you're not allowed to help your compiler
> >> optimize your program. In fact, specifying various compiler flags
> >> for various purposes (optimization, debugging, profiling, test coverage)
> >> is familiar to us all.
> >
> >Then why are people so obviously against this idea, if it is
> >connected with the name "EC++"?
>
> Why? Because that's not what EC++ is. EC++ is described by a
> (readily-obtained) document. What that document describes sounds
> nothing like what you say you want.
Is it really a ready descripion and not just a draft?
>
> If you are arguing for better compiler support for embedded-system
> programmers, then we are in total agreement. If you are arguing
> for EC++, then we are in total disagreement.
My impression was the following:
There's a need for better support with embedded-system programming,
and there's a group trying to standardize the necessary changes, and
the standard that is planned will be called EC++. There's also a draft
which is not at all satisfying, but since it's just a draft, it can
still be changed - f.ex. to add a sentence that EC++ compilers must
support full C++ as well.
If that impression was wrong, I'm sorry that my comments didn't
fit.
[...]
---
[ 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: No Author
Date: No Date Raw View
Regards.
--
+ Marcus Barnes, Technical Staff mailto:marcus@multigen.com +
+ Multigen Inc. http://www.multigen.com +
+ 550 S. Winchester Blvd. phoneto:1-408-556-2654 +
+ Suite 500 San Jose CA 95128 faxto:1-408-261-4103 +
[ 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: No Author
Date: No Date Raw View
Now, some of the optimizations it might want to carry out simply
aren't allowed by the current standard. However, I think the more
telling point is that the current definition of things leads people
AWAY from the correct mind set: instead of attempting to design the
library routines more intelligently, the present mind set is one of
leaving the library routines as "stupid" as possible, and leaving all
the intelligence up to the programmer.
Now, I'm certainly not trying to impugn the intelligence of
programmers (after all, I like to think of myself as one, and prefer
no to believe I'm a complete idiot) but in most cases, the compiler
has a much better basis for an intelligent decision about the
algorithm to use than the programmer does, at least for portable code.
--
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: No Author
Date: No Date Raw View
2 [...] In
the first alternative (delete object), the value of the operand of
delete shall be a pointer to a non-array object created by a new-
expression, or a pointer to a sub-object (_intro.object_) representing
a base class of such an object (_class.derived_). If not, the behav-
ior is undefined. [...]
3 In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a
base class of the operand's dynamic type and the static type shall
have a virtual destructor or the behavior is undefined. [...]
[...]
5 If the object being deleted has incomplete class type at the point of
deletion and the complete class has a non-trivial destructor or a
deallocation function, the behavior is undefined.
So if the class has a non-trivial destructor or allocation function,
the expression delete p is only defined if at least one of the following
is true:
- The pointer points to a single object whose real type is the static
type of *p. In this case the size of the object *is* sizeof(*p),
there's no need to look it up.
- The pointer points to a base class of the object, and the object
has a virtual table (because it has a virtual destructor). In this
case, the size could be stored in the vtbl.
So the only case where the size needs to be stored would be for
objects without non-trivial destructor and/or a deallocation function,
since only those can be deleted with a pointer to incomplete type.
One could even remove the need to store the size in that case by making
that size a symbol at class definition time, and referring to that
symbol at the delete expression. This is possible, since delete
with base class pointers is only allowed for virtual destructors,
and virtual destructors are never trivial (since the implicitly
declared destructor isn't virtual, if you don't inherit from
a class with virtual destructor, there must be an explicitly
declared destructor in the inheritance graph and only implicit
destructors can be trivial - see 12.4/3).
So we really have three different requirements:
malloc(): must store the size for free()
new: need not store the size, since delete can calculate it
new[]: need not store the size as well, but must store the element count
Anything I've missed?
---
[ 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: No Author
Date: No Date Raw View
1.7.1.2 Member functions [depr.strstreambuf.members]
void freeze(bool freezefl = 1); Effects:
If strmode & dynamic is non-zero, alters the freeze status of the
dynamic array object as follows:
--If freezefl is false, the function sets frozen in strmode.
--Otherwise, it clears frozen in strmode.
1.7.1.1 strstreambuf constructors [depr.strstreambuf.cons]
.. virtual ~strstreambuf(); Effects:
Destroys an object of class strstreambuf. The function frees the
dynamically allocated array object only if strmode & allocated != 0
and strmode & frozen == 0. (Subclause _lib.strstreambuf.virtuals_
describes how a dynamically allocated array object is freed.)
---
[ 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: No Author
Date: No Date Raw View
[ 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: No Author
Date: No Date Raw View
template <class T, class Allocator = allocator<T> >
class vector {
public:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
<snip>
reference operator[](size_type n);
const_reference operator[](size_type n) const;
On the other hand, if you use the default allocator<T>, you're safe
because allocator<T>::reference is a typedef for a plain old T&. Then
all
you have to remember is to account for the lifetimes of references if
the
vector is changed.
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
[ 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: No Author
Date: No Date Raw View
The majority of the members on the EC++ committee are Japanese
microcontroller manufacturers. As a technical translator (J->E) who has
translated a lot of data sheets and manuals related to Japanese
microcontrollers and their development environments, it sounds to me as
though you have no idea of the difficulties the Japanese have in providing
software for their products. Given their limited manpower resources,
implementing (or even dealing with) all of C++ is simply not an option, at
least for the relatively smaller players. Yet even a subset of C++ would
make life much easier for developers. (I.e., full C++ is just too hard for
the struggling sub-sub-sub-contractors where the work is actually done.)
In other words, there is a real problem, and the people who have this
problem are working to create a workaround. I don't see anything wrong with
that. Especially since they are doing it in a reasonably open and public
manner.
> 3. Standardizing a single subset ignores the needs of everyone who
> needs any of the features omitted, or who has no need for many
> of the features included. It's a procrustean bed.
Pete Becker already pointed out that this is wrong. Which leaves all three
of your objections shot down.
David J. Littleboy <davidjl@gol.nonspam.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: No Author
Date: No Date Raw View
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
[ 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: No Author
Date: No Date Raw View
--
( reply-to address changed to avoid the spammers,
use the following e-mail address )
daveg T unpronounceable D T com
http://www.unpronounceable.com/daves
[ 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: No Author
Date: No Date Raw View
- Tendra C++: uses some homegrown LL(1) parser generator and uses the
backtracing in the scanner technique. For some symbols the scanner starts
to save token streams, and when the parser recognizes that it can't parse
a statement it backs up and tries another alternative.
- Open C++: uses a normal bison parser and the same trick. Probably the
smallest and most readable freely avaiable C++ parser [I have not looked
at the free PCCTS C++ grammar, that might be readable too]
- GNU C++: uses a rather non standard grammar and uses many tricks in the
grammar to avoid backtracking, but that seems to cause many problems and
I hear there are plans for EGCS to rewrite the parser to use the grammar
from the standard and a scanner backtracing technique too.
Bison was certainly not designed to parse LALR(n), n>1 grammars, but the
scanner backtracing trick is well understood. I wouldn't call it elegant or
fast, but it works.
-Andi
---
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
The "shall" in 15.4 means that the implementation must provide a
diagnostic message, and that the results are undefined.
You can't throw a void, so it isn't obvious what a throw specification
of void ought to mean. If it means "any type", it is redundant, since
the absence of a throw specification means the same thing.
---
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: No Author
Date: No Date Raw View
---
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: No Author
Date: No Date Raw View
Bjarne is personally responsible for reducing the number of
components in STL by a factor of two. He was trying to make it
as small as possible to placate the opposition.
Since, just like you, I didn't find which ones, I guess Stepanov
is talking about components which weren't implemented at the time,
(or he simply didn't have time to document them properly --
see http://www.sgi.com/Technology/STL/drdobbs-interview.html
for the history of how STL was being introduced into the standard),
but he thought should have been included in the standard anyway.
The things he explicitly mentions (in the canadian URL) are -- singly
linked lists, multidimentional containers, graphs, and hash tables.
He probably had even more in mind. I agree that all four are needed,
but I am not sure that they belong to the standard. Probably not.
-=-=-=-=
Nathan Myers <ncm@nospam.cantrip.org> wrote:
: Oleg Zabluda <zabluda@math.psu.edu> wrote:
: >Hankel O'Fung <hkfung@ust.hk> wrote:
: >: Dear all,
: >
: >: 1) Please forgive me if this is an old question: what is the reason
: >: for not accepting hash table as part of the standard library?
: >
: >My understanding is that impossibility to guarantee anything
: >about performance.
: I mean no disrespect to Oleg, but this had very little to do with it.
Like I've said, since I was turning coffee into the theorems at the time,
and was nowhere near C++, those are only my guesses. Still, it's
an educated guess. There is a very strong push behind hash containers.
If an equally strong push was behind, say, a singly linked list,
or a two-dimentional vector, I think it would be accepted in a jiffy.
Hash containers were not. Now, why is that? The above is my guess, why.
I understand that there were issues, like timing of the proposals and
such. I think (hope) they were secondary.
Independantly on this, there are fundamantal difficulties with the
formalization of the proposal. Namely, the impossibility to guarantee
anything meanigful about performance, even for the library-provided
hash functions (at most for classes defined in stdlib, but most likely
just for integral types and strings), plus a huge burden on users to
provide their own hash functions for user-defined types. My guess
(just a guess) is that it was unclear if a container, with such an
awkward definition belongs to the standard. I think that it is still
unclear. Requiring a user to provide less<T> was already pushing it.
Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
[ 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: No Author
Date: No Date Raw View
(On the other hand, I haven't looked at the issue in detail. It's
likely that any change that would make this work like I want would
break something else more important.)
--
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 orientie objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading
---
[ 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: No Author
Date: No Date Raw View
-- Gabriel
---
[ 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: No Author
Date: No Date Raw View
>
> ARM also says (about overloaded functions), "One could imagine declaring
> all functions called f friends by a single declaration, but doing so
> would be a bit indiscriminate. It would enable a user to grab access to
> a class simply by declaring a function f with a hitherto unused argument
> type."
<snip>
> >If the intent
> > of the standard was to prevent the client from discovering a way of misusing
> > a class, I have some very bad news: in C++ it is always possible for the
> > client to misue a class. That's a non-issue, utterly beside the point.
>
> The intent of of the standard was to prevent accidental misuse of a
> class but not intentional misuse.
This is another meritless and useless analogy. I could see some merit in this
analogy if the user wanted the following code to be well-formed:
template<template<class X> class U>
class Foo {
template<class X> friend class U<X>;
};
But this is NOT the issue right now. And personally, I don't see any
philosophical reason why this shouldn't be valid C++ code except that, at the
current time, it would just be one more headache for compiler writers, who
already have enough work ahead of them trying to implement what's already in
the standard. The whole point of friend declarations is to allow the user to
specify that certain apparent violations of encapsulation are OK. And since we
have this mechanism in place, the user should be able to do whatever they want
with it.
As you yourself say, one of the major tenets behind C and C++ is that the user
shouldn't be prevented from doing dumb things (like violating encapsulation or
performing all kinds of awful casts). Rather, the user should be prevented
from UNKNOWINGLY doing dumb things. And this arbitrary restriction, which
Jaakko Ja:rvi pointed out at the beginning of this thread, completely violates
this tenet. If the user declares that some function or class is a friend, then
they did not accidentally do this. They had a reason. And neither compilers
nor standards have any business questioning the reason.
--
Ian Haggard || ian@shellus.com (work) || IanHaggard@juno.com (home)
GNU/Linux -- "Oh, no, Mr Bill!" || #define employer_opinion !my_opinion
---
[ 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: No Author
Date: No Date Raw View
struct Outer::Inner; // "error cannot introduce a qualified type"
is illegal!
At first glance it would appear one would do something such as:
struct Outer::Inner;
Outer::Inner *ptr;
This next declaration would not work since there could possibly be
Inner defined at global scope somewhere:
struct Inner;
--------------B702B25DB2B5A755E1BCB149
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<HTML>
<B>Referring to Section 3.4.4 in Draft: 2 December 1996</B>
<BR><B> Elaborated Type Specifiers</B>
<P>if one was to define a nested class such as:
<P><B>// In file_A.h</B>
<BR><B>struct Outer {</B><B></B>
<P><B> struct Inner {</B>
<BR><B> int a;</B>
<BR><B> };</B><B></B>
<P><B> int b;</B>
<BR><B>};</B>
<BR><B></B>
<P>If in another translation unit such as foo.cc, it was undesirable to
include the entire header file "fille_A.h" but I wanted to make
<BR>reference to class Inner for the purposes of declaring either a pointer
or reference such as:
<P><B>Outer::Inner *ptr;</B>
<P>how would one go about generating a forward declaration for this construct?
<P>From reading the Draft it appears that a forward declaration such as:
<P><B>struct Outer::Inner; // "error cannot introduce
a qualified type"</B>
<P>is illegal!
<P>At first glance it would appear one would do something such as:
<P><B>struct Outer::Inner;</B>
<BR><B>Outer::Inner *ptr;</B>
<BR><B></B>
<P>This next declaration would not work since there could possibly
be Inner defined at global scope somewhere:
<P><B>struct Inner;</B>
<BR><B></B> </HTML>
--------------B702B25DB2B5A755E1BCB149--
---
[ 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: No Author
Date: No Date Raw View
"The contents ... are the same as the Standard C library headers <math.h>
..., with the following additions: ...
In addition to the double versions of the math functions in <cmath>, C++
adds float and long double overloaded versions of these functions, with
the same semantics."
That makes it clear that <cmath> contains abs(float) and
acos(long double), for example, but the section goes on to list all
the extra signatures explicitly.
Author: No Author
Date: No Date Raw View
"Each C header, whose name has the form name.h, behaves as if each name
placed in the Standard library namespace by the corresponding cname
header is also placed within the namespace scope of the name-space std
and is followed by an explicit using declaration (7.3.3)"
Notice it says each name in the <cname> header is in the <name.h>
header. In other words, the only difference between <cmath> and <math.h>
is the effect of namespace std.
---
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: No Author
Date: No Date Raw View
// STL-style C function ;-)
extern "C" void foo (int* begin, int* end);
template<class iterator>
void f (iterator begin, iterator end, continuous_storage)
{
foo (&*begin, &*end);
}
template<class iterator>
void f (iterator begin, iterator end, unspecified_storage)
{
size_t s = distance (begin, end);
void* p = operator new (sizeof (*iterator) * s);
iterator_traits<iterator::value_type> v =
unnitialised_copy (begin, end, p); // please check arg
order
foo (v, v + s);
copy (v, v + s, begin);
destroy (v, v + s);
}
--
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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: No Author
Date: No Date Raw View
15Whenever a class object is copied and the original object and the copy
have the same type, if the implementation can prove that either the
original object or the copy will never again be used except as the
result of an implicit destructor call (_class.dtor_), an implementa-
tion is permitted to treat the original and the copy as two different
ways of referring to the same object and not perform a copy at all.
In that case, the object is destroyed at the later of times when the
original and the copy would have been destroyed without the
optimization.
---
[ 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: No Author
Date: No Date Raw View
Helmut
--
---
[ 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: No Author
Date: No Date Raw View
If the FDIS does not get enough "Yes" votes, the Committee then must
figure out how to satisfy more national bodies, modify the draft, and
return to the CD stage, sending out yet another draft for comments.
We don't expect that to happen, because representatives of national
bodies which had concerns have informally said they expect a "Yes" vote.
Assuming the vote passes, the FDIS becomes the actual International
Standard.
Tracking the standards process:
If you want to track the standards process and keep current with
proposed and accepted changes, you must join, or have your
employer join, the standards committee. Input from the general
public is solicited only at well-defined points in the process.
(Committee members as individuals sometimes solicit or accept
input at arbitrary times.)
But membership in J16 is open to all. Being a member does not
require any particular level of participation. Many members join
simply so they can receive all paper and electronic mailings and
keep abreast of the process. It is also much easier for members
to discuss (via committee email) issues they particularly care
about, than it is for non-members who lack the direct communication
channel. If your organization (company, university, or government agency,
for example) is a member, you are by ANSI rules allowed access to
all the committee work -- documents, email, meeting attendance, etc.
It is up to the institutional member to make whatever arrangements
it deems appropriate for providing such access to you.
If you are unwilling or unable to join the C++ Committee even as
non-participating member, but still want to track its progress, you
might try cultivating a friendship with someone who is on the committee.
If you don't like the process, you could work with your national
standards body to try to get the process changed. Many of us on
standards committees dislike parts of the process, but don't have
the option of ignoring the rules. We have had limited success in
getting some procedures changed.
---
Steve Clamage, stephen.clamage@sun.com
J16 chair
[ 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: No Author
Date: No Date Raw View
Did something change? Or did I miss something (most likely)?
--
Tony Cook - tony@online.tmx.com.au
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: No Author
Date: No Date Raw View
/*
* Try /dev/tty.
* If that doesn't work, use file descriptor 2,
* which in Unix is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
tty = open("/dev/tty", OPEN_READ);
if (tty < 0)
tty = 2;
A browse through the source for more or less would be more or less
worth your while. :-)
Cheers,
Marcelo
--
______________________________________________________________________
Marcelo Cantos, Research Assistant __/_ marcelo@mds.rmit.edu.au
Multimedia Database Systems Group, RMIT / _ Tel 61-3-9282-2497
L2/723 Swanston St, Carlton VIC 3053, Aus/ralia ><_>Fax 61-3-9282-2490
Acknowledgements: errors - me; wisdom - God; sponsorship - RMIT
---
[ 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: No Author
Date: No Date Raw View
Second, for F to be a viable function, there shall exist for each
argument an implicit conversion sequence (13.3.3.1) that converts that
argument to the corresponding parameter of F. If the parameter has
reference type, the implicit conversion sequence includes the operation
of binding the reference, and the fact that a reference to non-const
cannot be bound to an rvalue can affect the viability of the function.
So "foo-1" is not viable, and "foo-2" is chosen.
However, many current implementations allow binding of non-const
references to temps because older compilers (e.g. cfront) allowed it.
Some implementations may give a bogus ambiguity error for the above
example.
-- 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: No Author
Date: No Date Raw View
Now, there' no mention of linkage here. Indeed the only mention of
linkage
in the whole chapter 8 is in a note about the linkage of an array with
cv-qualified name. Now, a numerator is a constant expression. So what
should deny the usage here?
BTW, 100 has no linkage as well. I *really* hope that doesn't make
int a[100];
illegal! :-)
---
[ 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: No Author
Date: No Date Raw View
|> 7 ... converting an rvalue of type
|> "pointer to T1" to the type "pointer to T2" (where T1 and T2
are
|> object types and where the alignment requirements of T2 are
no
|> stricter than those of T1) and back to its original type yields
the
|> original pointer value,
The notion of alignment is clearly useful here, even if it
isn't clear how such guaranty can be useful (I even think
that an implementation where reinterpret_cast<short*>
(long_ptr) == 0 is conforming - but we are shifting from the
subject).
(2) using lvalue with a different type than the normal one
Code reading a double as if it was a float is clearly
non-portable; there is no question about that.
double d = 3.;
float* fp = reinterpret_cast<float*> (&d);
cout << *fp; // undefined behaviour
In particular, these tricks are disallowed whatever the
relative alignment of double and float; not only it's
obviously tricky and non explicitly defined, but the
standard makes it explicitly undefined:
Author: No Author
Date: No Date Raw View
> 15 If a program attempts to access the stored value of an
> object through an lvalue of other than one of the following
> types the behavior is undefined 48) :
> - the dynamic type of the object,
...
> - a char or unsigned char type.
They are also disallowed by the fact that reinterpret_cast
isn't guarantied to give a pointer to a valid object (even
in the char case, which looks like an ommission in the draft),
so 3.10/15 seems useless as you can't get such a lvalue anyway.
Alignment doesn't seem to play a big role in this story.
I want to go back to 3.10/15:
It says 'the dynamic type'; I believe that in C it says
'declared type'. (So in C, what is it when the object has
not been declared ?) Then, there are two cases:
(2i) new'ed object, for any placement or normal form of new
(2ii) malloced or operator newed object
(2i) The object is created with new (peal) Type (peal)
The notion of alignment seems to play a role, as the storage
returned by the corresponding operator new has to be
suitable for construction (large enough & aligned).
(2ii) malloced or operator newed object
Here it's clear that the object is suitably aligned from the
std. But it isn't clear at all that accessing it ok. Well, if it
has a non-trivial ctor, then you must construct it anyway
you we are back to (2i). If it's a POD however, I don't know
why it's ok to do that:
SomePOD x = {1, 2};
SomePOD* p = operator new (sizeof (SomePOD));
*p = x; // is it valid to do that ? undefined behaviour ?
The problem is that I can't find a definition of dynamic
type for POD in the draft (and no, what intro says about
that isn't a definition).
I'd like to hear a clear explannation about what the
dynamic type is.
So alignment seems to play some role, but only on where
you can construct objects, not on use of the objects.
Conclusion: IMO, when it comes to the memory model and
the definition of well defined memory access, the DWP
isn't very clear. Some changes are necessary.
In particular, [expr.reinterpret.cast] doesn't make char
a special case and should be completed.
--
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: No Author
Date: No Date Raw View
|> Note that sizeof(*p) differs from &(*p) in that the latter, in
|> general, requires reading p, while (as long as p is not an array)
|> sizeof(*p) can be determined at compile time.
Author: No Author
Date: No Date Raw View
There is an additional similar case in C++: (*p).f() (or its equivalent
p->f()), where f is a static member function. Again, all the compiler
needs from the expression `*p' is the type. On the other hand, unlike
sizeof, there is no local indication as to this fact -- a change in a
declaration in a distant include file could cause the code to suddenly
break. For this reason, the C++ draft standard specifies explicitly
that the expression to the left of the . or -> must be evaluated, even
if the results are not needed. (A compiler is free to remove the
evaluation under the as-if rule if it can determine that the evaluation
has no observable side effects. And that in determining this, it can
ignore all cases of undefined behavior, e.g. the possibility of p being
null, so that if the expression contained undefined behavior, the
observable behavior may not be the same.)
Note that in both cases, whether the compiler "needs" the evaluation is
not relevant -- what counts is that in one case, the standard says that
evaluation will not take place, and in the other, that it will.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ 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: No Author
Date: No Date Raw View
If, how, and why C++ should follow C when C adds a feature to deal with
problems that already have solutions in C++ are very interesting questions.
Similarly, if, how, and why C should follow C++ when C++ provides a
feature that is clearly useful within C are very interesting questions.
C and C++ are so closely associated (in reality and in the minds of many
people) that what harms the one usually harms the other. I suspect that
more coordination of their evolution is needed.
- Bjarne
Bjarne Stroustrup, AT&T Labs, http://www.research.att.com/~bs
---
[ 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: No Author
Date: No Date Raw View
The unary * operator denotes indirection. ... if [the operand]
points to an object, the result is an lvalue designating the object.
... If an invalid value has been assigned to the pointer, the behavior
of the unary * operator is undefined.^42
Footnote 42 asserts that:
... Among the invalid values for dereferencing a pointer by the
unary * operator are a null pointer, an address inappropriately
aligned for the type of the object pointed to, and the address of an
automatic storage duration object when execution of the block with
which the object is associated has terminated.
Note that the Standard speaks only of "the behavior of the unary *
operator," and for that behavior to be "undefined" the Standard does
not require that there be an (attempted) access to the object that is
pointed to. (I assume that the situation is similar in C++.)
Tom Payne
---
[ 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: No Author
Date: No Date Raw View
In COM/OLE programming in C++, the system defines a lot of interfaces as
pure virtual base classes. The easiest way for me to create an class B that
supports some collection of these interfaces is to multiply inherit from
them. However, if I don't want to allow class D, derived from B, to
override my implementation of some method, I can't use multiple
inheritance. The work arounds for this are all much more complex than
adding the qualifier 'final' to a method declaration.
---
[ 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: No Author
Date: No Date Raw View
: produced the following:
: Access violation occurred at 0x...: Attempt to access 0x....
: Unknown error
: I presume Borland International do not know better than the great man
: himself. At the least they should have given a slightly more useful
: diagnostic message :->
I'm guessing that the message was really from the system followed by
the stuff about shuting down the program, in this case the compiler.
If that one line produced that error at compile time, bcc does have a
real problem. OTOH if it was a runtime error, other code could easily
be the problem. On the third hand, if you used the purge function and
produced that error at compile time, g++ also has a problem with it
giving slightly more useful diagnostics ;-)
void purge (deque/* was set */<Shape*>& s) {
transform(s.begin(), s.end(), s.begin(), delete_ptr);
}
Note that purge is incorrect in the first printing (which I have) and
maybe in the second also. The errata available at Stroustrup's
homepage (follow the link from the awl page listed on the back cover)
replaces set<> with deque<>. Transform may not be used in this way
with a set since the elements are const. The errata are there because
Mr. Stroustrup is very open to constructive comments on the book. If
you have really found an error, let him know.
I tested this with <int*> to avoid the extra class. Using set, g++
complained about s.begin/end on a non-aggregate. Nonsence, but it is
a diagnostic for an invalid program. With deque/vector, it gives a
unification error. Providing a delete_int_pointer compiled fine.
Unification errors are common with g++2.7. The code seems reasonable
to me; however, ...
Is the delete_ptr<> really deducable?
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: No Author
Date: No Date Raw View
The value of uncaught_exception() can help you decide whether
to exit a destructor via an exception, or to skip the exception
and press on regardless. If uncaught_exception() is true,
exiting via an exception will result in terminate() being
called.
--
Steve Clamage, stephen.clamage@eng.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 ]
[ 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: No Author
Date: No Date Raw View
Inheritance as a message routine
Author: No Author
Date: No Date Raw View
Multi-Inheritance and Interface
Given this definition, nobody can say that multi-inheritance is a special
case of inheritance and should not be used, or that designs using
multi-inheritance are not pure.
I would like to ask the compiler to generate message intercepting from
multiple objects to another one.
If you admit inheritance ( and there are reasons not to admit it), you have
to admit multi-inheritance.
However, from a practical point of view, it is often hard to implement
multi-inheritance. It is why people don t like it. But if you respect the
rule given above, you will need inheritance 10 times fewer, and
multi-inheritance 100 times fewer.
A special case of inheritance is the use of interfaces : an interface is an
abstract class, with no code. It allows a programmer to build the what
and the how-to side in a single object. As it is the case with
multi-inheritance, this functionality is not crucial, and can be
implemented by hand. It avoids many problems of implementation (no
diamond configuration, can be used in any language, as it is done in COM,
etc.), but it is a very special case of inheritance. It does not permits
easy reuse of code ( there is no code in an interface), and often all the
classes which share an interface have to implement the same functionality,
since this functionality can t be stored in the interface.
Dynamic Multi-Inheritance : from objects to agents
Let s go back to my favorite example. One should note a problem : if I add
a another raw-control to my button at run-time, I must dynamically change
the definition of TBUTTON in order to inherits from this control and
intercept the messages. It does not mean that my definition is wrong, but
it show one of the major limitations of the OOL : they don t allow dynamic
multi-inheritance. As it is the same with encapsulation, interfaces and
polymorphism, this feature is not necessary, but would allow be to be more
productive and have my program simpler.
The delegation model is not better than the inheritance model. Use
inheritance when the link is static, delegation when is dynamic.
A good perspective is given by STROUTRUP in Design and Evolution of C++ .
Class TButton : public Tcontrol* control {
Virtual Void SetText();
}
Class TText : public Tcontrol{
}
Class TShape : public Tcontrol{
}
Dynamically, I can make the button to inherit from a TText or a TShape.
? It is a equivalent to delegation , but I don t have to declare a member
and implements many wrappers : if there are 10 methods in TControl, I have
to implements 10 wrappers in Tbutton wich will just send the message ( do a
call) to the control.
? This cannot be done using inheritance, since I would have to declare as
many kinds of Tbutton there are TControl ( TTExtControl, TshapeControl,
etc.). So Dy
We have the advantages of delegation (flexible) and inheritance(build-in
feature of the OOL, easy to use)
We can extend it by :
Class TButton : public Tcontrol* parents[] {
Virtual Void SetText(Tcontrol* Sender);
}
I can dynamically add parents to the button. When I call Text.SetText
= LOIC , Tbutton::SetText is automatically called, I don t have to code
this delegation.
There are the basis for a Agent Oriented Language which use these features
to automatically reconfigure the inheritance net. If you have a look upon
the 'design patterns',
it's clear that the semantics constructs of C++ ( like dynamic inheritance
and so one ) are useful to softaware design : productivity will increase
(more high-level constructs),
the design will be more flexible (the static or dynamic type of a link is
not decisive) and C++ will be easier to use ( no time to spend on tricky
architectures).
For a good start, have a look on delphi ( try..finally, metaclass,
properties, description of the classes available at run-time to display the
properties) and java ( synchronized method, wich enable a less-OS dependent
code).
thanks for your read.
---
[ 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: No Author
Date: No Date Raw View
It doesn't seem like this would provide much more functionality than a
callback class. I suspect its feature is that an __callback pointer can be
called in a context that expects a normal function pointer, and it will
have access to its object. I.e. you can get OO functionality when you're
using a library that performs non-OO callbacks.
--
Barry Margolin, barmar@bbnplanet.com
BBN Corporation, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.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: No Author
Date: No Date Raw View
1. Simple containers: No ordering operators defined
2. Identifiable containers: operator == and operator !=
3. Sortable containers: all comparison operators
Without this heirarch, <list> can be more trouble to
use than it is worth.
Question:
How can this heirarchy be added to an implementation
and still be in conformance with the standard?
Or a better question: How can the standard be extended
to include this heirarchy without breaking existing code?
Suggested answer:
To keep from breaking existing code, the list<...>
and other sequence templates must be left as it is with
the ordering operators defined. Additional classes for
the simpler containers need to be added that are
inherited by the more complex containers.
An example of the names for the simpler list classes
in order of decreasing complexity would be:
1. list
2. unique_list
3. unordered_list
---
[ 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: No Author
Date: No Date Raw View
Assuming I have a struct that I wish to be written, why can't
I just send it by address?
Author: No Author
Date: No Date Raw View
Perhaps I'm missing something obvious. Thanks in advance
for your assistance.
---
[ 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: No Author
Date: No Date Raw View
Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ 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: No Author
Date: No Date Raw View
--
Christopher M. Dearlove, | chris.dearlove@gecm.com
GEC-Marconi Research Centre, | Tel: 01245 242194 Int: +44 1245 242194
Gt. Baddow, Chelmsford, CM2 8HN, UK | Fax: 01245 242124 Int: +44 1245 242124
---
[ 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: No Author
Date: No Date Raw View
There are compilers that allow it and some that do not.
--------------------------------------------
David Bradley davidb@datalytics.com
Software Engineer
Datalytics, Inc. http://www.datalytics.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: No Author
Date: No Date Raw View
"The underlying type of an enumeration is an integral type that can
represent all the enumerator values defined in the enumeration. It is
implementation-defined which integral type is used as the underlying
type for an enumeration except that the underlying type shall not be
larger than int unless the value of an enumerator cannot fit in an int
or unsigned int. [.. ans some more]"
Incidently MSVC 4.2 would complain when trying to use enums in cout
expressions.. The error was that the call to ostream::operator << is
ambiguous because it was overloaded for int, unsigned int , long etc etc...
so one was forced to write cout << int(SomeEnumVal) ; or what ever
the type u wanted it converted to.. looks like they have still not got this
one right..
hope that helps
-bom
---
[ 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: No Author
Date: No Date Raw View
-Wmissing-prototypes
Warn if a global function is defined without a previous prototype
declaration. This warning is issued even if the definition itself
provides a prototype. The aim is to detect global functions that
fail to be declared in header files.
Jim.
---
[ 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: No Author
Date: No Date Raw View
I believe the C rule reflects compatibility with early C, which did
not have the "void" type. In pre-standard C there was no way to
specify that a function did not return a value.
--=20
Steve Clamage, stephen.clamage@eng.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 ]
[ 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: No Author
Date: No Date Raw View
Surely - as auto_ptr's implementation is straightforward - it is
simple to define a further class, auto_array (say) which has all the
places where auto_ptr has operator delete() replaced by operator
delete[]().
So then I could do:
auto_array<char> p(new char[SIZE]);
// do stuff using p, including (say) passing it to an OS API fn
// don't worry about freeing before we return, or about exceptions
Here's a straightforward implementation (based on the auto_ptr
implementation in Scott Meyers' "More Effective C++")...
template<class T> class auto_array
{
public:
explicit auto_array(T *p = 0) : Ptr(p) {}
template<class U> auto_array (auto_array<T>& y) :
Ptr(y.release()) {}
template<class U> auto_array<T>& operator=(auto_array<U>& y)
{
if (this != &rhs) reset(rhs.release());
return (*this);
}
~auto_ptr() { delete [] Ptr; }
T& operator*() const { return *Ptr; }
T* operator->() const { return Ptr; }
T *get() const { return Ptr; }
T *release() { T *old = Ptr; Ptr = 0; return old; }
void reset(T *p = 0) { delete [] Ptr; Ptr = p; }
private:
T *Ptr;
};
Is there any reason why the standard didn't include this? Is there a
way of doing it with the standard library types?
Paul Moore.
PS What is the standard get_temporary_buffer() function intended for?
I can't think when I'd use it...
------------------------------------------------------------------------
Paul Moore gustav@morpheus.demon.co.uk
------------------------------------------------------------------------
... Back Up My Hard Drive? I Can't Find The Reverse Switch!
---
[ 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: No Author
Date: No Date Raw View
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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: No Author
Date: No Date Raw View
In the STL, I think that this conversion is required to be implicit
although it doesn't say so explicitly. In most current implementations
of STL, it must in fact *be* an integral type, and not just convertible
to one. On the other hand, it isn't hard to think of cases where the
converions was not required to be implicit; I think, in fact, that no
harm would be done to the STL if this were the case.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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: No Author
Date: No Date Raw View
> The rule in C++ is essentially the same
> as in standard C. Two signatures are required to be recognized by all
> conforming implementations, but any implemenation may choose to recognize
> other signatures as well.
Ah, I see; that wasn't the impression I was getting. Thanks for the
clarification.
--
Jim Hyslop
jim.hyslop@leitch.com
"If you want to see the rainbow, you
gotta put up with the rain."
-- Dolly Parton
---
[ 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: No Author
Date: No Date Raw View
2 An object that is partially constructed will have destructors executed
only for its fully constructed sub-objects. Should a constructor for
an element of an automatic array throw an exception, only the con-
structed elements of that array will be destroyed. If the object or
array was allocated in a new-expression and the new-expression does
not contain a new-placement, the deallocation function
(_basic.stc.dynamic.deallocation_, _class.free_) is called to free the
storage occupied by the object; the deallocation function is chosen as
specified in _expr.new_. If the object or array was allocated in a
new-expression and the new-expression contains a new-placement, the
storage occupied by the object is deallocated only if an appropriate
placement operator delete is found, as specified in _expr.new_.
And from 5.3.4:
18If any part of the object initialization described above terminates by
throwing an exception and the new-expression contains a new-placement,
if the type of the object being created is a class type, a name lookup
is performed on the name of operator delete using the same lookup
rules as those used to find operator new (_class.free_). Otherwise, a
name lookup is performed on the name of operator delete in the scope
of the new-expression (or in global scope for ::new ). If the lookup
succeeds and exactly one of the declarations found matches the decla-
ration of that placement operator new, then the matching placement
operator delete shall be called (_basic.stc.dynamic.deallocation_).
If no matching placement delete is found, propagating the exception
does not cause the object to be deleted. [Note: this is appropriate
when the called operator new does not allocate memory; otherwise, it
is likely to result in a memory leak. ]
19A declaration of placement operator delete matches the declaration of
a placement operator new when it has the same number of parameters
and, after parameter transformations (_dcl.fct_), all parameter types
_________________________
17) This may include evaluating a new-initializer and/or calling a
constructor.
except the first are identical.
20If placement operator delete is called, it is passed the same argu-
ments as were passed to placement operator new. If the implementation
is allowed to make a copy of an argument as part of the placement new
call, it is allowed to make a copy (of the same original value) as
part of the placement delete call, or to reuse the copy made as part
of the placement new call. If the copy is elided in one place, it
need not be elided in the other.
---
Herb Sutter (mailto:herbs@cntc.com)
Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada L5K 2N6
Tel 416-805-9088 Fax 905-822-3824
---
[ 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: No Author
Date: No Date Raw View
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
(((taz *= yuk.ack()) >>= grom).blarf() += farg).mungex();
Apparently many people think that this is incredibly nifty and clever;
personally i start a quick search for my barf bag. I hope that these
people find Lisp so they can go away and do such things all they want.
Note that any code that uses this feature can easily be re-written to
not do such things. At worst you'll end up with more named quantities.
It's a matter of opinion whether this change improves the code, but i'd
argue that the result is almost always more clear and more maintainable.
If things were up to me, i would always have assignments return `void'.
That prevents such overly nifty code, which i think is a good thing.
But that's my style, and of course other people may disagree.
Now to my point: Why does STL require this convention? The STL code
can easily be written to never use the result of an assignment, right?
--
Joe Keane, amateur mathematician
---
[ 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: No Author
Date: No Date Raw View
To make B::foo(int i) visible in D and allow your code to compile, you
need to add a "using-declaration" to D. In this case, change the
declaration of class D to
class D : public B {
public:
using B::foo; //bring B::foo into D's scope to allow overloading
void foo(int, const A &);// redefined function, but we'd
// like the same default behavior
};
Now B::foo(int i) is declared in the same scope as D::foo(int, const
A). This now allows D::foo(int, const A) and B::foo(int i) to both be
visible in D as overloaded functions.
For more information about this "using-declaration" technique, see:
1) THE C++ PROGRAMMING LANGUAGE, Appendix A, Section a.1.r.3.3.1.3
(ANSI/ISO resolutions: Standardization: Classes)
2) THE DESIGN AND EVOLOUTION OF C++, Section 17.5 (Namespaces:
Implication for Classes)
>and 2) if so, why?
See THE DESIGN AND EVOLUTION OF C++, Section 3.5.2 (The Birth of C++:
Virtual Functions: Overriding and Virtual Function Matching) and
Section 3.5.3 (Base Member Hiding)
[ 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: No Author
Date: No Date Raw View
[expr.add] 5.7/4
For the purposes of these operators, a pointer to a nonarray object
behaves the same as a pointer to the first element of an array of
length one with the type of the object as its element type.
(I think that your other examples are also well-defined in light of
this paragraph.)
Daveed
[ 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: No Author
Date: No Date Raw View
where T has copy constructor?
I found that many C++ compilers accept the code without any warnings.
And of cause very unfortunately from C point it is OK.
--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
[ 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: No Author
Date: No Date Raw View
I'm also not sure I want it. There is a delicate balancing act between
enough guarantees to be usable, and inventing, rather than standardizing
existing practice. While such detail seems (and probably is) reasonable
for ios::ios, you've chosen a simple example.
|> Is there a way to generalize
|> this so that it only needs to be said once?
So specific, probably not. My point 2, above, can probably be expressed
in a general way that, while not optimal for most functions, is
acceptable. Another poster recently gave an indication of where to
start (defining "well behaved functions", and specifying that the
library is "well behaved" IF all of the member functions of the
instantiation types are "well behaved").
generalizablbbbb
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, tudes et r alisations en logiciel orient objet --
-- A la recherche d'une activit dans une region francophone
[ 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: No Author
Date: No Date Raw View
It doesn't say anything specifically about pointer-to-member-functions,
but if we replace the 'T' in the above like this
typedef void (C::T1)(D&)
typedef void (C::T2)(B&)
and apply the above rule, I'd have to say that it was illegal since
the types T1 and T2 are not the same. Though in your example the
conversion would be safe as far as I can tell. My skill in reading
the DWP is rudimentary at best, though, so I think a second opinion
is in order.
marco
[ 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: No Author
Date: No Date Raw View
If this is allowed, would parallel evaluation be allowed?
Both interleaved and parallel evaluation of function arguments introduce problems
with code that changes any global state, like global variables.
[ 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: No Author
Date: No Date Raw View
|> Unless
|> the answer to both questions is an unequivacal yes, there is a problem.
The answer will never be an unequivacal yes, as long as the committee is
made up of human beings.
|> > |> Given that all instances of an allocator have to be
|> > |> functionally equivalent, is there a real need to specify special
|> > |> constructors for each allocator instance? Is it worth the
|> > |> complication and potential misunderstanding this feature has
|> > |> demonstrated it can cause?
|> >
|> > The whole point is that *not* all instances of an allocator must be
|> > functionally equivalent. And the implementation must adapt, using
|> > different techniques when the instances are not functionally equivalent.
|> > In cases where this test is significant, the implementation is free to
|> > partially specialize the template for the default allocator (for which
|> > all instances *are* functionally equivalent). Most of the time, I
|> > imagine that the cost of the extra test is negligible. I also imagine
|> > that in every case where all instances are functionally equivalent,
|> > operator== will be an inline function, so the compiler should be able to
|> > optimize the test away, and dead code elimination remove the more
|> > complex branch which will never be taken. (This is well within the
|> > scope of what, I believe, most optimizers today are already capable of
|> > doing.)
|> Ask the converse question -- why not have all the instances of an
|> allocator be functionally equivalent? If they were, the extra complexity
|> complexity ends up in conversion constructors between instances with
|> different allocators. That looks like a better place for it than buried
|> in odd corners of the algorithms.
In sum, it is better to put the added complexity in the users lap,
rather than to hide it away somewhere deep in the implementation. I
don't agree.
|> > The only real problem I see today is that the only document we have on
|> > all of this is the draft standard. Which is a draft, and is a standard,
|> > not an instructional text. Which means that the driving ideas, and how
|> > it is meant to be used, are often not immediatly apparent.
|> That and no one is likely to implement the new stuff completely before
|> the standard passes. Some degree of certainty that a reliable
|> implementation exists and that this fancy piece of brick-a-brack really
|> serves a useful function would make me and I suspect a lot of other
|> folks happier.
I suspect that most of the implementors (Rogue Wave, et al.) are waiting
mainly for a decision concerning exception safety in the library. This
will have a major impact on their code. In addition, I can imagine that
they are waiting for a compiler which supports member templates and
partial specialization.
The problems that I see are *NOT* in the library itself. The solution
to this problem is known, and is not that difficult. At least, if your
compiler supports partial specialization. Most don't at present.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, tudes et r alisations en logiciel orient objet --
-- A la recherche d'une activit dans une region francophone
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
(I have access to two library implementations, one of which leaves the
state of the stream as good, the other sets it to failbit after reading
the 4 chars into the string.)
--
Ken Rice
rice@tiac.net
---
[ 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: No Author
Date: No Date Raw View
'nuff late-night rambling...
--
Dan Muller
danm@zipnet.net
---
[ 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: No Author
Date: No Date Raw View
OTOH, [conv.ptr] clarifies the ARM somewhat in stating that "an
_integral_ constant expression rvalue that evaluates to zero"
yields the null pointer. In the ARM, a "constant expression that
evaluates to zero" is required, but a reference to a section that
explains integral constant expression is given. So, the question
is, can a conversion sequence that transformes the double literal
"0.0" to a null pointer be considered when looking for a viable
overloaded function?
Kurt
--
| Kurt Watzka Phone : +49-89-2180-6254
| watzka@stat.uni-muenchen.de
[ 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: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
8.3.2 [dcl.ref] /4
"A reference shall be initialized to refer to a valid object or
^^^^^
function. In particular, null references are prohibited; ..."
IMHO it is a verbose lead-in to the next sentence which really says
something.
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: No Author
Date: No Date Raw View
template<class T>
T max(T a, T b) { return a>b?a:b; }
template int max<int>(int, int); //instantiation
/* OR: */
template int max<>(int, int); //instantiation
const char* max<const char*>max(const char* a, const char* b)
{ /* specialization */ }
/* OR: */
const char* max<>(const char* a, const char* b)
{ /* specialization */ }
My questions are:
1. Is the above correct? I heard there are some recent changes
in this area.
2. Is the following still legal:
int max(int, int); //instantiation??
Thanks!
Marian
--
----------------------------------------------------------------------
Marian Hellema AT Computing, UNIX training and consultancy
email: marian@atcmp.nl P.O. Box 1428, 6501 BK Nijmegen
phone: +31 24 3527225 the Netherlands
---
[ 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: No Author
Date: No Date Raw View
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
---
[ 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: No Author
Date: No Date Raw View
1 A template can be referred to by a template-id:
template-id:
template-name < template-argument-list >
template-name:
identifier
template-argument-list:
template-argument
template-argument-list , template-argument
template-argument:
assignment-expression
type-id
template-name
Notice the third-last line, "assignment-expression".
Call me dumb, but I must ask what does this mean? What does the
expression specify, a type or a value? Will an assignment be made at run
time?
Can you give me any examples of templates specialised with an
assignment-expression?
Thankyou.
David
---
[ 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: No Author
Date: No Date Raw View
b) "An object of a class with a non-trivial default constructor
(_class.ctor_), a non-trivial copy constructor (_class.copy_),
a non-trivial destructor (_class.dtor_), or a non-trivial copy
assignment operator (_over.ass_, _class.copy_) cannot be a member
of a union,"
DB> This is a major reduction of the restrictions found in ARM, where all
DB> kinds of constructors or assignment operators were excluded. Here is
DB> also a note to give the explanation by the assumption, any member
DB> functions and especially assignments would usually expect a correctly
DB> constructed object.
JS> No. It is merely a more precise statement of the same
JS> restrictions using more technical terminology.
JK> This is, in fact, exactly the restriction in the ARM. All that has
JK> changes is the way things are described. In the ARM, classes may or
JK> may not have constructors (destructors, assignment operators). In the
JK> current standard, *EVERY* class/struct has a copy constructor, an
JK> assignment operator and a destructor; the distinction is that some of
JK> these are trivial.
I still disagree totally. Please tell me what I'm reading wrong.
The ARM (mine is an early edition, 1990) does a complete restriction
against *any* constructor, destructor or user-defined assignment for
union member objects. (Section 9.5, page 182). The only explanation for
this rule was already summarized in my original posting, quoted above;
it has nothing to do with bitwise copy.
The WP indeed allows member objects with a rich set of constructors
and assignment operators. It does only <g> cripple the 4 most commonly
used special member functions, exactly naming them, into trivialness.
- default constructor
- destructor
- copy constructor
- copy assignment
I assume this exact enumeration implies all other variants of constructor
and assignment in member objects are free for user defined versions.
So the following sample seems perfectly legal with the WP, not with ARM.
The commented lines are the trivialness-required special member functions.
class Bar {
public:
// Bar(); // trivial default constructor
// Bar(const Bar&); // trivial copy constructor
// ~Bar(); // trivial destructor
// Bar& operator = (const Bar&); // trivial copy assignment
// plain member function - no problem
Bar& operator_assign(const Bar&);
// some other constructors - I see no problem here
Bar(int);
Bar(float);
// several other simple assignments are allowed
Bar& operator = (int);
Bar& operator = (float);
// these are assignments too, see ARM 5.17 or [expr.ass]
Bar& operator += (const Bar&);
Bar& operator -= (const Bar&);
Bar& operator *= (const Bar&);
Bar& operator /= (const Bar&);
// ... data members etc.
};
union Foo {
Bar bar;
// ... others
};
DB> So you can have any special assignment operator or constructor for
DB> your member objects, any but the most common and useful ones.
JK> Correct. The reason is simple: assignment, copy, default construction
JK> and destruction of a union must be correctly defined without the
JK> compiler knowing which element the union actually contains. The set
JK> of forbidden operators are those that the compiler might be called
JK> upon to use in implicitly generated code.
But why would you like to provide your own constructor and assignments?
Maybe because you have added some side effects, like range checking or
trigger a reference counter.
If you only use arguments matching your custom routines, this will work
fine. But if you accidentally assign one Foo.bar to another, your
side-effects won't take place because the WP prevented your custom copy
assignment operator.
It is even impossible to hide the unwanted implicit constructors and
copy assignment into privacy, to make your compiler produce an error
message.
Foo foo1;
Foo foo2;
foo1.bar = 4711; // applies your side-effects
foo2.bar = foo1.bar; // just trivial assignment here due to WP
-----
a) "A union shall not have base classes. A union shall not be used as
a base class."
JK> Without this rule, you either break the address rule, or you impose
JK> some special class layout on unions.
The union has no special class layout? I would say it is very special.
"a class whose member objects all begin at offset zero"
-----
/* my sample of union inheritance */
JK> This is generally handled better by an abstract base class and
JK> virtual functions.
Sure, I like polymorphic objects. But if you have a vast amount of
really small objects you may get tempted to use the reduced footprint
of a (1 or 2 byte) tag instead of a sizeof(ptr) vptr.
It is also slightly faster to load these unions from a binary file
than from a stream, allocate, dispatch and construct every single
object and retrieve every single member.
-----
/* union with longlong as member */
DB> If you are lucky to have some native long long datatype, then this
DB> would be legal code. If you already had to implement your own
DB> class longlong, now you lost the chance to use it (here).
JK> This is a problem, but... how would the compiler know when to call
JK> the constructor/destructor of your longlong?
Sorry for the wrong sample, longlong may work with trivial c/dtor and
copy operations. The same is with some class Complex.
Let's reconsider a class "string" and reference-counter features as
sideeffects. The answer for your question - how would the compiler
know? - came with my conclusion as quoted below: Just tell him.
Here the union constructor itself gets responsible for construction as
the correct union variant - e.g. choose the correct discriminator tag,
like "empty".
DB> I would generally prefer " ... constructors and destructor of member
DB> objects are ignored, if not explicitly called by the union's ctor/dtor.
DB> The union's implicit default copy constructor / assignment does a
DB> binary copy instead of memberwise copy. Objects <containing a vptr>
DB> cannot be member of a union" - Please pardon my shortcut on vptrs.
The missing sample for this:
class Member {
public:
Member();
// ...
};
class Other {
public:
Other();
// ...
};
union Union {
Union();
Union(int);
// ...
Member m;
Other o;
};
Union::Union()
{ // call none of the base member constructors
}
// call Member::Member() using a wellknown notation
Union::Union(int a)
: m()
{ }
// deluxe variant - but this would mean a severe extension
Union::Union(int tag)
: tag==1 ? m() // call Member::Member()
: tag==2 ? o() // otherwise call Other::Other()
{ }
-----
c) "A union can be thought of as a class"
DB> Here you accept the implications of 12.8.8 and 12.8.13 on implicitly
DB> defined copy constructor and copy assignment. The already trivial
DB> copy constructor/assignment of the member objects will then result
DB> in one large repetition of copies from and to the same memory locations.
DB> To avoid this behaviour I would strongly recommend to implement your
DB> own copy constructor or assignment whenever you use a union, because a
DB> memberwise copy is usually not desired.
JK> Basically, if you study the restrictions on unions carefully, the
JK> rules are such that a bitwise copy *must* be legal for assignment and
JK> copy construction. This is the only type of copy the compiler can
JK> cope with in the absense of a discriminator to tell it which element
JK> of the union is valid.
JK> IMHO: if you feel that your union needs a copy constructor or an
JK> assignment operator, you are probably doing something wrong, in the
JK> sense that you are trying to use unions in a way that they are not
JK> intended. (As they are defined in the standard. If they were defined
JK> differently, they might have different reasonable uses.)
I knew, but some compiler implementors forget their homework here.
If for any reason (generated source) you have a union with lots of
members, you may accidentally get lots of redundant code. This is
another reason for implicit bitwise copy.
And if the trivialness requirement were removed from the copy
operations, like in my (very draft) replacement text quoted above,
you would also loose the equivalence.
Author: No Author
Date: No Date Raw View
Why did you then not stay just with the POD union? With the
differentiation between POD union and non-POD union you already
got the higher degree of complexity, only to undo this with lots
of additional words.
My first incident with this problem went what I would call a
user's way instead of the implementor's sight: How can we use
it? Instead of "How to infer the implicit implementation?"
Here I felt invited by the WP to use most of the member object
assignments and than fell into the trivialness trap.
If your intention is bitwise copy as implicit copy for the union
itself, why not just call it by its real name instead of hiding
behind "trivialness"?
"The implicit union copy constructor and copy assignment apply
bitwise copy."
No trivialness restrictions on the member objects!
If someone then decides to have member objects with other copy
constructor or assignment semantics, he/she just has to provide
own union copy operations.
-----
d)
DB> Why is there no anonymous struct?
JS> The committee (as a body) does not find arguments for
JS> orthogonal design appealing. It is hard to demonstrate
JS> why orthogonal design is good to those who have little
JS> experience with orthogonal systems -- most of us,
JS> considering the horrid systems we're forced to work with
JS> most of the time.
JK> Agreed here. Although I really don't see it as worth the bother.
JK> (I could do without anonymous unions, too.)
You won't need the anonymous struct, because you already said you
don't use unions.
-----
Some new questions:
e) "At most one of the member objects can be stored in a union at
any time."
Has anybody already thought about the memberwise implicit operations in
regard to this rule?
OK, we'll meet again at the bitwise copy, but this is at least nowhere
explicitly mentioned in the WP.
-----
f)
Why is [class.mem] 15 restricted to POD structs as union members?
vptrs are already excluded for union members, and I would still
ask to exclude them when dropping the trivialness.
------------------------------------------------------------------
Dirk Becker dirk@becker.adviser.com
Harderweg 76, 22549 Hamburg, Germany Tel. +49 40 80783143
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
summarized in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]
Author: No Author
Date: No Date Raw View
typedef typename Allocator::size_type size_type;
...
static const size_type npos = -1;
It is my understanding that the Allocater::size_type should be an unsigned
flavour. If this is indeed the case, are we to interpret nops as having the
value (size_type)(-1) ?
--
John Hickin Bell-Northern Research, Montreal, Quebec
(514) 765-7924 hickin@bnr.ca
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
The next page [ARM] gives a justification for this decision, the
jist of which is that in a chain of derived classes, a "best match"
may be found deep in the base class which will surprise programmers
using the derived class.
Cheers,
Russell Johnston
<rjohnsto@edge.net>
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
Handle h ; // class Handle overloads operator.()
h.display() ; // h returns a reference to a Bitmap object
// whose display() is then called
Operator.() was not overloaded because you can achieve exactly this same
effect without it, if the clas Handle has a set of member functions
matching those in Bitmap, The Handle member functions can simply make
inline calls to the Bitmap member functions; they can also override to
change behaviour where necessary:
class Handle {
Bitmap & ref ;
public:
bool display()
{
return ref.display() ;
}
} ;
Various implementations of this kind of scheme are described in the
literature, for example Coplein, My favourite implementation is where the
handle class, and the genuine class, both inherit their interface from
the same abstract base class.
David Byrden
|| C++ training for professional programmers ||
|| My opinions ARE those of my employer. ||
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Potentially, I suppose, the standard could make more guarantees
concerning synchronous signals (those raised by `abort' or `raise');
in fact, the C standard does. Is it worth it?
There is one practical case that might be worth discussing: SIGFPE. I
don't think that the standard can make too many guarantees about this
one, since on some hardware, it is asynchronous. But on many
implementations, it is synchronous, or close enough to being
synchronous, so that you could throw an exception from it. It would
be nice, as a quality of implementation issue, if such implementations
actually documented this fact, and the fact that you could count on
it.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
-- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
The currently available implemention (from HP) is somewhat error
prone, and cannot be used in the presence of exceptions. Given the
price that HP (a commercial firm, in business to make money) asks for
it, however, I hardly think anyone has a right to complain. Their
implementation does offer a sound basis for a more solid
implementation, and has allowed many people to become familiar with
the idioms faster than would have otherwise been possible.
Safer implementations are possible; Cay Horstman, I think, has already
made one available. Exception safe implementations are also possible.
(It is also an open question how far one wants to go here. I would
accept, for example, that an exception from the comparison function
when inserting into a map results in undefined behavior; if comparison
can throw an exception, an STL map is perhaps not the appropriate
container.)
If the complaint is based on the fact that the Draft Standard is not
particularly clear, well, STL was added just before the Draft was made
public, so the text was added very hurriedly. The (not officially
public) September draft is already significantly better; given the
quality of the people working on it, and the amount of work they are
investing, I see no reason to doubt that the final version will be OK.
(It will *NOT* be a tutorial, of course. That is not the purpose of
an ISO standard.)
My pet peave, of course, is that there is no hint in the current
version as to the requirements of the template classes/functions when
the instantiation classe throws an exceptions, but I'm sure that this
is on someone's work list, somewhere, and will be addressed in the
final standard. (In the meantime, I'd love a hint as to what
direction this will take. Will an exception from a comparison
function cause undefined behavior?)
There is a lack of tutorial material at present, but this is only
because the library is new. I expect that new C++ tutorials will
present vector<T> instead of the classical C style arrays, for
example. (And you surely don't mean to imply that vector<T> is more
error prone than the C style arrays, do you?)
So why would anyone want the C++ standard *not* to include STL?
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
-- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
C. STL<ToolKit>:ObjectSpace at 1-800-OBJECT-1
most C++ compilers
code is well documented
comes with tutorial with over 200 elementary
examples that have just been placed in the public
domain available via anonymous ftp from
butler.hpl.hp.com at
/stl/examples.Z or .zip for PC
These examples are a good place to start.
They have taken Alex's public-domain copy from butler.hpl and modified it
extensively for portability to cfront, efficiency and some ease-of-use
improvements..
--
Shankar Unni E-Mail: shankar@sgi.com
Silicon Graphics Inc. Phone: +1-415-933-2072
URL: http://reality.sgi.com/employees/shankar
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
quit
bert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
3.7.3 Dynamic storage duration [basic.stc.dynamic]
These functions are always implicitly declared. The library provides
default definitions for them (_lib.new.delete_). A C++ program shall
provide at most one definition of any of the functions ::operator
new(size_t), ::operator new[](size_t), ::operator delete(void*),
and/or ::operator delete[](void*). Any such function definitions
replace the default versions. This replacement is global and takes
effect upon program startup (_basic.start_). Allocation and/or deal-
location functions can also be declared and defined for any class
(_class.free_).
18.4.1.1 Single-object forms [lib.new.delete.single]
void* operator new(size_t size) throw(bad_alloc);
...
Replaceable:
a C++ program may define a function with this function signature
that displaces the default version defined by the C++ Standard
library.
Jason
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
So, what I'm actually saying is that if it's possible to perform the
dynamic_cast without knowing the T being used, why not do so ?
My suggestion is that if the compiler encounters an expression like :
'dynamic_cast<ATypeInfo>(p)' were ATypeInfo is a 'const type_info&'
the compiler won't try to cast p to ATypeInfo, which will ALWAYS fail, but
it will try to cast p to the type ATypeInfo contains data for.
Have Fun,
Etay.
-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
valarray are not containers but matrices.??
nah that doesn't help.
|> A vector is a sequence, obviously. So is a list.
|> The very notion of iteration is inherently a question of
|> enumerating things: linearity.
I would disagree, at least for the meaning we normally give to
`iterator' in this context. An iterator does not formally impose an
ordering. In particular, in my implementation of SetOf (which uses
open hashing), if an element is inserted while an iterator is active,
it is undefined whether the element will be considered before or after
the iterator.
If you iterate through things you have created an order.
The order in which you went through the set.
This does not make the set itself have order only the access.
It is also true that the STL is a little weird about sets, etc.
Just a few thoughts,
Eric
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: No Author
Date: No Date Raw View
The ANSI/ISO C++ standards committee have adopted some changes to the
C++ language since the publication of the original ARM, and newer
versions of g++ (2.5.x and later) support some of these changes, notably
the mutable keyword (added in 2.5.0), the bool type (added in 2.6.0),
and changes in the scope of variables defined in for statements (added
in 2.7.0).
You can obtain an addendum to the ARM explaining these changes by FTP
from ftp.std.com in @file{/AW/stroustrup2e/new_iso.ps}.
(The addendum isn't complete, but it lists the major stuff).
--
-- Joe Buck <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Anagrams for "information superhighway": Enormous hairy pig with fan
A rough whimper of insanity
Author: No Author
Date: No Date Raw View
For that reason, I'd rather prefer another term if you're going to add a new
keyword. However, I wouldn't be so quick to regard Mr Boole's acheivement as
"utterly simply" just because you're only using one simplified version of
it. True, it's not the most complex theory in the world, but then *most* of
mathematics looks simple in hindsight, although that doesn't mean it's not
an important development.
BTW: Has anyone considered that under and specification-based extended integer
range (such as proposed by Frank Farance), it is possible simply to say
typedef int fast exact:1 logical_t;
Author: No Author
Date: No Date Raw View
``Since functions with different linkage may have different calling
conventions, a linkage specification may have a major effect on pointers
to functions. In particular, C++ functions that do not have the ellipsis
in their argument type may use a more efficient calling sequence than has
traditionally been used for C functions.''
My guess is this refers to the question which function is responsible for
(destructing and) discarding the arguments of a function call: the caller
or the callee? I know of at least machine architecture where the callee
can do this slightly faster than the caller can.
- Wil
Author: No Author
Date: No Date Raw View
> Look how quickly Java has entered the scene (see http://java.sun.com).
Languages almost always enter the scene quickly. This says little about their
long term viability or suitability for a particular purpose. Java was designed
for a quite different purpose than C++, and it is far from clear whether Java
will ultimately fullfil its promises (extensibility without sacrificing
security) in its "target market". The alternatives in this area (TCL, Perl)
don't look that bad.
Java certainly has some potential as an application programming language, but
lots of competition from Ada 95, Eiffel, Smalltalk, Oberon et al., some of
which have decades of experience in getting trampled by the success of C++.
> If the Java developers are smart, they will follow the Linux path rather than
> the C++ path.
I.e., they will have the language controlled by a single entity, rather than
make it an international standard? Well, at least from the current license,
it looks as if Sun intends to do just that.
Matthias
-----
Matthias Neeracher <neeri@iis.ee.ethz.ch> http://err.ethz.ch/members/neeri.html
"There once was an Age of Reason, but we've progressed beyond it."
-- Ayn Rand, _Atlas Shrugged_
Author: No Author
Date: No Date Raw View
I just browse back the other articles and found only two references about
"virtual static memner functions" :
Esa Pulkkinen wrote :
> They would add the guarantee that the functions wouldn't
> use any non-static members of the class even when overridden by the
> derived class (and of course nicer syntax).
This is really a design issue ...
Can be solved in other ways ...
And Matt Austern Wrote :
> Because there are some ways in which the semantics of a "static
> virtual" function are unclear, because it addresses only a minor
> convenience issue, and because it would complicate both the
> meaning of static member functions and of virtual member functions.
> As a practical matter, I think that those considerations are enough
> so that, at this late date, there is no chance of the committee
> approving this extension.
> There are some things that are currently true of all static member
> functions that wouldn't be true of "static virtual" functions, and
> there are some things that are currently true of all virtual member
> functions that wouldn't be true of "static virtual" functions.
> In other words, I believe that a "static virtual" function would have
> to be neither static nor virtual, but something else. A better way to
> think of it might be as two functions of the same name one of which is
> static and one of which is virtual.
Which I think says everything I wanted to say about this matter.
I guess that there is NO debate about the NO-need for "virtual static data".
"virtual static member functions" can be implemented using a simple
class-in-class design. Why add yet another feature ? ( when ther is NO overhead
in programming it ).
The ONLY feature I can think of which REALLY reduced programming overhead is
RTTI. Just look at the MACRO's each and everyone wrote to get RTTI working.
And I consider RTTI as a "feature" since it could be done otherwise but the
overhead was too big from the programmers point of view.
-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
Author: No Author
Date: No Date Raw View
How about "cool"?
C defined its special operators on integers, distinguishing zero and
non-zero, allowing all sorts of boolean programming by just using
integers, albeit less type-safely. Given this history of something so
written into the language, attempts to define a separate bool in C++ are
bound to compromise something.
My own preference in C is to keep using zero and non-zero ints, though
of course I would gladly use a bool type in a language that had it
designed in from the start. Perhaps a C++ bool will be separate enough
from C history that I can use it - I half hope so.
Tony Bass
--
# Tony Bass Tel: (01473) 645305
# MLB 3/19, BT Laboratories e-mail: aeb@saltfarm.bt.co.uk
# Martlesham Heath, Ipswich, Suffolk, IP5 7RE DO NOT e-mail to From: line
# Opinions are my own
Author: No Author
Date: No Date Raw View
My vote would be for 1, with deprecation of the implicit conversions.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
Of course, I hope that there is another reason for this, because the reason I
just described is brain-dead. Optimized and debuggable code should have the same
semantics to the greatest degree possible, and what I just described does NOT
have the same semantics -- one has run destructors before calling terminate, the
other has not. It is also unnecessary to make explicit provision for this in the
standard, because this is a quality-of-debugger-implementation issue -- any
debugger worth using will use a run-time library which checks for uncaught
exception first, and then trap to the debugger in the same way that debuggers
(under Unix, for example) intercept "bus error" or "segmentation violation".
Or, it could be for another brain-dead reason, namely one vendor does it
one way, the other does it another way, and neither intends to budge.
However, I am certain that I am completely wrong in all these suppositions,
and some wise and diplomatic member of the C++ committee will explain why
this is really so.
speaking for myself,
David Chase
Author: No Author
Date: No Date Raw View
A union can have member functions (including constructors and
destructors), but not virtual (10.3) functions. A union shall not
have base classes. A union shall not be used as a base class. ...
A union can have no static data members.
Best regards.
--
+-----------------------------------------------------------------------------+
| Derick R. Qua-Gonzalez | ________ |
| Department of High Energy Physics, California State University | \ / |
| dqua@Prometheus.EarthLink.Net | \ / |
| ``It is better to be hated for what one is, | \ / |
| than loved for what one is not.'' (A. Gide) | G \/ USA|
+------------------------------------------------------------------+----------+
| mQBNAy/qJJMAAAECANBCB543eTUkdG8Mqx6K2cm3WxCVtKY8ZbB9WY6A2Ne4dQi8 | PGP2.6.2 |
| xh7OxjHXP/eXp5BSbmVAihEGd7r+5g/yknko56kABRG0MERKUiBRdWEtR29uemFs | Public |
| ZXogPGRxdWFAUHJvbWV0aGV1cy5FYXJ0aGxpbmsuTmV0Pg== | KeyBlock |
| =70DW | 06.20.95 |
+------------------------------------------------------------------+----------+
Author: No Author
Date: No Date Raw View
I cannot believe that this is true and therefore must be missing
something. My questions are these:
what include file do I use to get SUN's string class?
Is the string class according to the standard?
If it isn't, how do I read from cin into a string?
Thanks for the information
Ray Swartz
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
>We also reached the equally amazing conclusion that any values in the
>enum, not catered for in the switch, should be a compiler error, not
>a warning.
That's totally wrong. Are you sure that you understand what the
semantics of the following _C_ code are?
switch (3)
{
case 1:
/* blah blah blah */
break;
}
--
-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- E-mail: rfg@segfault.us.com ----------- Purveyors of Compiler Test ----
---- finger: rfg@rahul.net ----------------- Suites and Bullet-Proof Shoes -
Author: No Author
Date: No Date Raw View
--
Robert Krawitz <rlk@tiac.net>
Member of the League for Programming Freedom -- mail lpf@uunet.uu.net
Tall Clubs International -- tci-request@think.com or 1-800-521-2512
Author: No Author
Date: No Date Raw View
--
Stephen Baynes baynes@mulsoc2.serigate.philips.nl
Philips Semiconductors Ltd
Southampton My views are my own.
United Kingdom
Author: No Author
Date: No Date Raw View
3.5.4.2 Array Declarators
Constraints
The expression delimited by [ and ] (which specifies the size of
an arrya) shall be an integral constant expression that has a
value greater than zero.
--
mitchell@mdd.comm.mot.com (Bill Mitchell)
Author: No Author
Date: No Date Raw View
Connect(); // ok, provided there are no name conflicts
ODBC::Connect(); // uses alias
Microsofts_ODBC_library::Connect();
Note that aliases are merely a compile-time shorthand. The full namespace
name is what governs link-time resolution.
Given the availability of the "aliasing" feature, library-providers will
probably choose to use very long namespace names, to eliminate any chance
of conflict. If each vendor includes their own Company name in each
namespace name that they offer, conflicts should not occur, and there
shouldn't be any need for a global "registry."
---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com The opinions I express are no one's but mine!
Author: No Author
Date: No Date Raw View
Disallowing what (seems to me anyway) an easy notation to support (given
that the examples above are supported today) will effectively stop us
from using typedefs in these situations and decrease the useful of
typedefs in general. (IMHO)
[Besides, using the argument given above I would think at least my
2nd and 4th (and possibly all) examples given above should also
be illegal if the destructor call is made illegal!]
I think the standards committee should at least reconsider this issue
and give specific wording on where typedefs can be used *outside*
of a class declaration. I also feel the issue should be reconsidered
purely from an orthogonality point of view.
[Disclaimer: Sorry, if this has been discussed before but I haven't been
following this thread too closely but from what I've seen the arguments
against allowing this construct (based on 7.1.3) are very weak.]
Cheers!
-- __
Brent McPherson | / _\ Alias Research Inc.
Senior Software Engineer | / / /\ 110 Richmond St. E.
E-Mail: bmcphers@alias.com | / / /\_\ Toronto, CANADA M5C 1P1
Phone: (416) 362-8558 ext.212 | \/_/\__/ Alian Nation: http://www.alias.com
--
Author: No Author
Date: No Date Raw View
> I'd say that that was an acceptable flaw in the scheme though, wouldn't you ?
[...]
Agreed. I would rather not attempt to make so fine a distinction.
Thanks for the clarifications.
Tony Bass
--
# Tony Bass Tel: (01473) 645305
# MLB 3/19, BT Laboratories e-mail: aeb@saltfarm.bt.co.uk
# Martlesham Heath, Ipswich, Suffolk, IP5 7RE DO NOT e-mail to From: line
# Opinions are my own
Author: No Author
Date: No Date Raw View
I am impressed by this definitive exposition of main. I have just minor
queries on (4),
> 4 Where main is defined as
> int main (int argc, char *argv[]) { /* ... */ }
> (i.e. the second of the definitions given above), the parameter argc
> shall be the number of arguments passed to the program from the
> environment in which the program is run, plus one. The value of argc
> shall be nonnegative and nonzero. argv[0] shall be a pointer to either
> "" or to the initial character of a null-terminated multibyte string
> (NTMBS) that represents the name used to invoke the program; where
> argc is greater than 1, argv[1] through argv[argc-1] shall be pointers
> to the initial characters of NTMBSs representing the arguments;
Is NTMBS intended to imply at least one character? The context slightly
suggests this, but in a Unix environment it is possible and often useful
to pass an empty string as argument, that is, "", a pointer to an ASCII
NUL byte.
Again in a Unix environment, argv[0] is at the invoker's disposal,
conventionally often a program filename, but sometimes not (eg a shell
invoked as "-sh" on login or as "sh" at other times). I think the
wording given may cover this, as "the name used to invoke the program"
carefully avoids talking about filenames, but I wondered if the
description of argv[0] could be unified to make no distinction between
empty and non-empty strings, perhaps just mentioning matters of
convention? Unix could meaningfully invoke a program giving it argv[0]
"", though I do not know of any example actually doing this.
> finally, the value of argv[argc] shall be 0.
Having seen some discussion of null pointers in standard C I dare not
question this! Thanks for some good text.
Tony Bass
--
# Tony Bass Tel: (01473) 645305
# MLB 3/19, BT Laboratories e-mail: aeb@saltfarm.bt.co.uk
# Martlesham Heath, Ipswich, Suffolk, IP5 7RE DO NOT e-mail to From: line
# Opinions are my own
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Believe it or not, this actually hit me in a real world situation. I spent
ages poking about with OMF dump tools to find the problem, and more ages
until I eventually tracked down the declaration of `main' that someone had
"helpfully" included in one of the application's headers.
I can only guess at why C++ compiler number five doesn't like declarations
of `main'. Perhaps it inserts "magic" entries into the symbol table for
`main' at the start of translation with special "this is a magic function"
flags, which *actual* declarations of `main' then overwrite, turning it
into a normal function. Who knows ?
The point is, that [basic.start.main] doesn't say that you may not have a
declaration of `main' apart from its definition. I believe that it should.
For one thing, such a prohibition prevents `main' from being declared
outside of the translation unit in which it is defined, thus denying the
programmer one way that he could take the address of `main', or call it.
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Note that granting something to the public domain is a complete
abandonment of all rights. You can't make something "PD for
non-commercial use." If your work is PD, other people can even modify
one byte and put their name on it.
The question I still have is will the final C++ standard be made
available electronically to committee members? Will an electronic
copy be made available or for sale to non members? Does ISO restrict
the distribution of the document (has anyone ever tried to get
permission to freely redistribute a document copyrighted by them
electronically)?
I believe ANSI has restrictions on electronic distribution, but if
some ISO member gets a copy of the Standard and they put it on their
Web site, ANSI can't do anything about it, right?
Jamshid Afshar
jamshid@ses.com
Author: No Author
Date: No Date Raw View
So I would be satisfied saying using vars before definition
(whatever their types, internal structures, etc.) is a bad practice,
and such code should not happen (it's a bug, or at least a potential bug),
same kind of stuff for using undefined variable in parameter passing.
So undefined behavior is OK, the less constraints the better, so
am I against any exhaustive enumeration.
Passing such an uninitialised var to a 'reference' (or using & operator on var)
should be OK, no access to value.
Author: No Author
Date: No Date Raw View
Regards,
Swee
Author: No Author
Date: No Date Raw View
"Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const object during its lifetime (3.8) results
in undefined behavior."
---
Steve Clamage, stephen.clamage@eng.sun.com
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Brian
--
Brian Syme, Software Engineer, Conic Systems Ltd.
bsyme@cix.compulink.co.uk, +44 (0)141 552 8473
Author: No Author
Date: No Date Raw View
>: bs@research.att.com (Bjarne Stroustrup <9758-26353> 0112760) writes:
>: >The standard is large (700+ pages), but that is not large compared to
>: >other standards for modern programming languages.
[...]
>: "Eiffel, the language" 594 pages
Without getting into the crux of this discussion, let me just make a
correction of fact, regarding ``Eiffel: The Language'' (Prentice Hall,
1992) of which I am the author. The page count given above is correct
(actually it omits the front matter - preface, table of contents etc.)
but it is NOT the size of the reference manual.
``Eiffel: The Language'' is several books in one: reference manual but
also tutorial, rationale, illustrations. It contains hundreds of examples
and many sections labeled ``comment'', ``caveat'', ``methodology'' etc.
So the book's length is not characteristic of the length of the language
definition.
A better figure is available for that purpose. A true reference manual was
recently produced for the body in charge of Eiffel standardization - NICE,
the Nonprofit International Consortium for Eiffel. That document, called
``Eiffel: The Reference'', is essentially an extract from ``Eiffel: The
Language'', discarding all the non-reference elements. (It is available by FTP.)
Although it is still an early draft, one may surmise that the final version
won't be too different. The current size of the document is exactly 100 pages,
with a large font and lots of white space.
This is the length that should be quoted in any comparative discussion.
--
Bertrand Meyer, ISE Inc., Santa Barbara
805-685-1006, fax 805-685-6869, <bertrand@eiffel.com>
Web home page: http://www.eiffel.com
ftp://eiffel.com
Author: No Author
Date: No Date Raw View
...what is the winning "OO Machine"...???
...will it be a Smalltalk machine...???
...an Eiffel machine...???
...a C+@ machine...???
...or a JAVA machine...???
One thing for sure...it will not matter if it is...Intel, SPARC, PowerPC,
6800, etc...hopefully, it will also not matter if it is UNIX or NT...also
hopefully, it will not matter if it is Windows 95 or X-Windows...
The real issue for the developer of the future will be...what is the
target virtual OO machine that supports the execution of the applications
or "applets" they develop...and what is the assumed set of classes that
can be reused...and how can I easily, deliver, test, and maintain this
software via the Internet (or other networks)...
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>With Applets, they get automatically loaded when you access the
>containing web page, *without* the permission of the
>owner/administrator of the system, and sometimes even without their
>knowledge. Without some kind of security measures, those programs,
>when run on a system like MSDOS without OS security, can conceivable
>trash any file anywhere on the system. Even on Unix, if they exploit
>one of the many security holes, they can do immense damage.
>
>So the language that is used to write Applets has to be different from
>the languages used to write other applications. You have to have some
>way of ensuring that executables generated for the language don't have
>the capability of violating security.
>
>None of the C derived languages on the market can meet that
>requirement - casts and pointers to data and functions can allow
>programs to violate the "contract" of a safe program, thus making it
>possible to violate security.
>
>So you need to restrict the language in ways sufficient to ensure
>security. That means cutting off access to unrestricted memory
>pointers, removing pointer subscripting, removing unchecked casts --
>essentially removing any feature that makes it impossible for the
>compiler to ensure safety. Once you'e removed all of that from most
>C-family languages, you've pretty well crippled them. So you need to
>extend them in ways that replace the crucial unsafe features with safe
>alternatives. So you add safe arrays and references. Enhance the type
>system to allow the flexibility that you got from casts with something
>typesafe. Build a module system to replace the unreliable #include.
>Add garbage collection, since it's become terribly hard to manage
>memory manually. Do all of that, and what you get will look an awful
>lot like Java.
>
>The only remaining question is: why do you want to start with C++ as
>the basis? And the answer to that is twofold:
>
>(1) Everyone knows C. If you use a language based on C, then 90% of the
> syntax will be readable by the majority of your perspective users. The
> fact that they don't need to learn to read and write a whole new syntax
> makes the language seem much more approachable to new users.
>
>(2) Object-orientation is darned useful. Especially for the application
> they had in mind.
>
>So, you want to start with an object-oriented variation on C. That
>means that really, there are two choices: Objective-C, and
>C++. Objective-C has a lot fewer users, and would be harder to make
>type-safe than C++. SO you start with C++.
>
>Makes perfect sense, neh?
>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
C+@ started with C...it looks like JAVA did the same thing...there
does not seem to be much "C++" in JAVA, unless you mean the C part
of C++...
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>Jim> Why is it that when Borland needs an Object Oriented language for
>Jim> their new flagship product line, Delphi, they DO NOT USE C++ ???
>
>Could it be because the company got started on Pascal, and so people
>inside really like working with it? Or perhaps because Microsoft is
>using C++, and they wanted to differentiate themselves? Nah. It *must*
>be some kind of conspiracy.
>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Differentiation is a very wise move by Borland...as I have stated before
any modern software company has to focus on "owning" a language...note
that NeXT finally purchased Objective-C to help ensure their future.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>Jim> Why do Sun and Borland continue to waste money on C++ ???
>
>Because they're both in the business of making money, and people are
>willing to pay lots of good money for C++? Nah, it *must* be some
>kind of conspiracy.
>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Most people that buy C++ are buying the C part of C++. Anyone that is
seriously working at the leading edge of OO, knows that C++ does not
deliver the OO part. (One of the only companies that seems to dispute
this is Taligent. They started on a good track by thinking through the
long term need for a true OO platform. Unfortunately, they got side
tracked by C++. Only time will tell if Taligent is able to recognize
the corner they are in, with C++).
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>Jim> Are Sun and Borland shareholders aware of the limitations of C++
>Jim> ???
>
>Why would Sun and Borland shareholders *care* about technical things
>like that? People buy stock to *make money*. All that a shareholder
>cares about is that the stocks s/he owns do well, and show a
>consistent profit. From an investment perspective, C++ seems to be a
>good gamble. Who cares if it's not *technically* superior to its
>competitors. All that shareholders care about is *market*
>superiority. And you make more money selling C++ than selling some
>unknown but superior alternative.
>
>But no. That must not be it. It *must* be an anti-C+@ conspiracy.
>
> <MC>
>
>--
>|| Mark Craig Chu-Carroll: <MC> || "Only love
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
I am glad that you note that C++ is a gamble. Many people have invested
in it, thinking it was a "sure thing". Since AT&T promoted it, it could
not lose. In that respect it was (or is) a "sure thing". The question
now for investors is, will C++ be able to deliver the "OO return on
investment"?
Only time will tell...us C+@s can all have a cup of Hot JAVA...
...while we continue to wait for C++ to deliver... :)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--
Jim Fleming /|\ Unir Corporation Unir Technology, Inc.
jrf@tiger.bytes.com / | \ One Naperville Plaza 184 Shuman Blvd. #100
%Techno Cat I / | \ Naperville, IL 60563 Naperville, IL 60563
East End, Tortola |____|___\ 1-708-505-5801 1-800-222-UNIR(8647)
British Virgin Islands__|______ 1-708-305-3277 (FAX) 1-708-305-0600
\__/-------\__/ http:199.3.34.13 telnet: port 5555
Smooth Sailing on Cruising C+@amarans ftp: 199.3.34.12 <-----stargate----+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\____to the end of the OuterNet_|
Author: No Author
Date: No Date Raw View
-Ic:\develop\myprog\h;c:\develop\stdcomp\include
The compiler will then search these directories for #include specifications
automatically. That should fix your problem I hope.
later,
Ben Scherrey
Proteus Technologies, Inc.
Author: No Author
Date: No Date Raw View
What does a template look like in C+@?
Sincerly,
Eric Biederman
ebiederm@cse.unl.edu
--
main(c,v,n)char**v,*n;{c>1?n=v[1],c=*n++,main(c,&n-1),putchar(c):0;}
Author: No Author
Date: No Date Raw View
Americans should not expect that their interests will be served "before"
any other country, because it appears that the C++ Standard will truly
be an international accomplishment lead by the ISO. Americans do not
have any inalienable rights to C++. This is one of the reasons why the
Inter(national)net should be used to communicate the status of the C++
standard. Also, Americans should not be held responsible for C++.
This is no different than if a large number of athletes trained at U.S.
universities for the Olympics but participated for their "home" country.
Americans should not be surprised that the number of "gold medals" they
win is dramatically reduced. Their so-called "citizens" really represent
other countries. As time goes on, maybe small groups of athletes will
gather together and form a country. This would guarantee that they make
their Olympic team and would help to equalize the medal count.
The fall of the Soviet Union implicitly means that there might be a
decline in the need for U.S. "nationalism". This will give rise to
"individualism". Maybe someday each person will be there own country,
each person will design their own computer language, and each person
will have their own class library. The Internet, the OuterNet and
Cyberspace may be the vehicle that allows these "individuals" to
communicate in this new world order.
In this new world order, when something like a language standard needs
to be developed, company and country boudaries do not really matter.
What is key is the ability to convene a group of 6 to 8 people that
are willing to merge their efforts. This may help to reduce the number
of computer languages from 6 to 8 billion to 1 billion. C++ will be just
one in a billion. The STL class library will be just one in a billion.
I predict that companies and countries will realize how expensive and
how inefficient it is to have a different programming language for
every half dozen people. Maybe groups of these groups will gather together
and find a common ground to reduce some of the overhead. At that point
the American National Standards Institute may be needed.
At this point in time, it appears that the ISO clearly has C++ positioned
as the next major international standard. Whether the ISO C++ will be
useful to anyone (or small group) remains to be seen. Referring to it
as ANSI C++ seems to be a big misnomer. Maybe someday, a real ANSI C++
will emerge once the dust settles on the ISO C++. Between now and then
it is likely that there will be hundreds of C++'s as people move
toward individualism and abandon their company and country allegiances.
In the new world order of software and systems, the allegiance is to
the Internet (or OuterNet) community. The traditional corporate and
municipal communities provide little support and take little interest
in what is happening in Cyberspace. This opens the "door" to Cyberspace
having it's own standards, independent of NOT ONLY corporations and
communities but also standards bodies like ANSI and ISO.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--
Jim Fleming /|\ Unir Corporation Unir Technology, Inc.
%Techno Cat I / | \ One Naperville Plaza 184 Shuman Blvd. #100
Penn's Landing / | \ Naperville, IL 60563 Naperville, IL 60563
East End, Tortola |____|___\ 1-708-505-5801 1-800-222-UNIR(8647)
British Virgin Islands__|______ 1-708-305-3277 (FAX) 1-708-305-0600
\__/-------\__/ e-mail: jim.fleming@bytes.com
Smooth Sailing on Cruising C+@amarans ftp: 199.3.34.12 <-----stargate----+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\____to the end of the OuterNet_|
Author: No Author
Date: No Date Raw View
|> You must know the precedence of the type "operators" to construct a fully
|> parenthesized declaration:
Finally, a point on which we agree fully.
|> int *const *x[10][4]; // Same as...
|> int *(const (*((x[10])[4])));
|> // Array-of-10 arrays-of-4 pointers to const pointers to int!
(Should be "int (*const (*((x[10])[4])))", according to the standard.)
|> int *const (*x[10])[4]; // Same as...
|> int *(const ((*(x[10]))[4]));
|> // Array of 10 pointers to arrays of 4 const pointers to int!
(Should be "int (*const ((*(x[10]))[4]))", according to the standard.)
|> It's like an arithmetic expression,
Which is why I use the term, type expression.
|> where some type operators are applied
|> before others. The postfix `array-of' operator has higher precedence than the
|> prefix `pointer-to' operator, so *x[n] means *(x[n]), not (*x)[n].
Correct.
|> >> So in declarations, `const' is sometimes a prefix operator; but other times
|> >> it's a specifier (like `int') that can only appear at the start of the
|> >> declaration and applies to every name being declared in it. This is really
|> >> ugly. Looks like a mistake in the language design.
|> >
|> > Const is never an operator. Const is never a `specifier' (whatever that
|> > is).
|> You know very well what a `specifier' is. You used it yourself earlier on in
|> your posting:
|> < In the declaration specifier, it modifies the basic type (which is the only
|> < type defined in the declaration specifier)
|> > Const is a qualifier, which in most cases, qualifies whatever is to its
|> > left.
|> Sure, it's a qualifier. It's also a specifier. The C++ Programming Language,
|> 2nd Ed., r.7.1, is called "Specifiers." r.7.1.6 is called "Type Specifiers."
|> The grammar there defines <type-specifier> as one of several things, including
|> <simple-type-name> (e.g. `int') and also including the word `const' all by
|> itself.
Sorry. I was thinking of declarators.
`Const' is a keyword. Within a declaration, it can occur in two
contexts:
1. In the declaration specifier. The declaration specifier is an
unordered list of specifiers, and in this context, `const' is a
specifier. With regards to the claim that const is a prefix operator,
this is an *unordered* list; there are no operators (in any sense),
and certainly no concept of prefix or postfix.
2. As part of a cv-qualifier-list[opt] in a declarator. A
cv-qualifier-list[opt] is a (possibly empty) unordered list of
{`const', `volatile'}. Since `volitile' occurs relativly rarely, I
will suppose that when Sam Fenster claims that `const' is a prefix
operator, he really means that `cv-qualifier-list' is a prefix
operator (in the mathematical sense of operator, of course). (I might
add that in my discussion above, *I* have used `const' as a
contraction/example of a cv-qualifier-list.) In this context, I think
I can accept that in a loose sense, the cv-qualifier-list is a sort of
an operator, which modifies what *precedes* it (i.e.: it is a postfix
operator).
A cv-qualifier-list can only occur in two places in a declarator:
following the closing paratheses of a function (with the semantic
constraint that the function must be a class member function), in
which case, it declares that the function ("operator" ()) is const, or
in a ptr-operator, where it follows a `*'. In this case, the grammar
binds it most tightly to the *preceding* `*', and the text explicitly
states: "The cv-qualifiers apply to the pointer and not to the object
pointed to."
I do not like to use the term `operator' here (although I did, just a
little above:-). The C++ declarator grammar is not define in terms of
operators. In the production ptr-operator, it const an operator on
`*', or vice versa. My reading of the grammar is that the token
string "* const" is an operator, but that the individual members are
not.
If this all seems complicated, welcome to C++.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
During compiliation time, the time needed by the compiler to handle a
"USES Tools" is degrees smaller than if you had to "{$I tools.uni}" (this
is the way of including a file into pascal). This is because the compiler
is only reading the type- and debug-information in memory and adding it to
his internal tables. Thats all. No lexing, no parsing, no code generation
or building of intermediate information. Bleedingly fast.
I also like to have all information of my black box in ONE source file
(and not to search for *.cpp, *.cc, *.h, *.hpp and so on).
But i realize that it helps a lot that the macro scheme of Turbo-Pascal is
much limited in respect to c++ and that there also are no templates. But i
see no impossibility for introducing a unit or module concept into c++. It
has many advantages during the development of applications.
---
Holger Schurig _ | Das Wort vom Kreuz ist denen, die verloren
holger@infsys.swb.de <_>< | gehen, eine Torheit. (1. Korinther 1:18)
Author: No Author
Date: No Date Raw View
The example above may look a bit trivial, but things mess up very fast if class D
is part of a more complex class hierachy.
A possible solution could be to declare class D as sharable e.g.
share class D : public B
{
...
};
so the compiler could at least generate a warning, if it has to include any
additional data items which are fixed during link or load time.
Given this it would be relatively safe to overlay binary data with a structure,
a technique which is quite often used in C:
D* buffer;
void* GetCommunicationBuffer()
...
buffer = (D*)GetCommunicationBuffer();
...
I admit, this doesn't look pretty, but it avoids copying Megabytes around and
works fine if the objects within the buffer are consistent.
Note that this doesn't involve checking the user defined object members. So a
programmer could write without getting any warning:
share class X
{
int* p;
};
// process A
int a_global;
...
X* pax = (X*)SharedMem(sizeof(X)); // allocate some shared memory
pax->p = &a_global;
// process B
X* pbx = (X*)GetShared(); // somehow get the address of pax
int i = *pbx->p;
This would not work of course, but catching this kind of thing must be left to
the programmer.
Rereading this, I note, that the above doesn't help in any way if you REALLY need
virtual functions within the transferred objects. A possible - and quite portable
alternate solution would be the following construct, but it involves copying the
data:
class SharedObj
{
// here stand only data and nonvirtual functions
};
class VirtualObj : public SharedObj
{
// add virtual methods here
public:
VirtualObj(const SharedObj& s) : SharedObj(s) {}
};
Any comments are welcome.
B. J. Brunner
Author: No Author
Date: No Date Raw View
As with all rules, there are exceptions: the main one here concerns
static objects. It is perfectly possible (and regrettably frequent)
to call member functions of a not yet constructed static object. (The
usual symtom of this is a core dump before you reach main.)
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
One last clue...check the second paragraph of the middle column on page
18...of the April issue of Upside...
I will see you on the OuterNet...an AT&T-free zone....
--
Jim Fleming /|\ Unir Corporation Unir Technology, Inc.
%Techno Cat I / | \ One Naperville Plaza 184 Shuman Blvd. #100
Penn's Landing / | \ Naperville, IL 60563 Naperville, IL 60563
East End, Tortola |____|___\ 1-708-505-5801 1-800-222-UNIR(8647)
British Virgin Islands__|______ 1-708-305-3277 (FAX) 1-708-305-0600
\__/-------\__/ e-mail: jim.fleming@bytes.com
Smooth Sailing on Cruising C+@amarans ftp: 199.3.34.12 <-----stargate----+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\____to the end of the OuterNet_|
Author: No Author
Date: No Date Raw View
>...just remember, 50 years ago someone stood up to the Germans
>(and Hitler)... [...]
^^^^^^
We have invocation of Godwin's Law. Repeat, we have invocation of
Godwin's Law. Death of this thread is therefore imminent.
-sbigham
--
Scott Bigham | The opinions expressed above are
dsb@cs.duke.edu | (c) 1995 Hacker Ltd. and cannot be
http://www.cs.duke.edu/~dsb/ | copied or distributed without a
= PGP spoken here = | Darn Good Reason(tm).
Author: No Author
Date: No Date Raw View
>In article <3mh4oo$pho@duke.cs.duke.edu>, dsb@cs.duke.edu says...
>>From the Holy Book of <3mgscf$ob6@News1.mcs.com>
>> as spake by jim.fleming@bytes.com (Jim Fleming) :
>>>...just remember, 50 years ago someone stood up to the Germans
>>>(and Hitler)... [...]
>> ^^^^^^
>>We have invocation of Godwin's Law. Repeat, we have invocation of
>>Godwin's Law. Death of this thread is therefore imminent.
>Are you suggesting that everyone should just forget Hitler and Germany
>from 1933 to 1945?
[further abuse deleted]
You haven't the faintest idea what I'm even referring to, do you?
Here's a relevant quote from the Net.Legends FAQ
(gopher://dixie.aiss.uiuc.edu:6969/00/urban.legends/net.legends/Net.Legends.FAQ):
"This has mutated, in true UseNet fashion, to encompass *any*
continuing thread; if you mention Hitler or Nazis out of the blue, the
thread is sure to die irrelevantly soon (and, incidentally, you've
lost the argument, whatever it was)..."
Go and read the FAQ and be enlightened. [And beware; at the rate you're
going, you might just find yourself listed in it before too long... ;) ]
-sbigham
--
thump thump thump thump thump thump thump thump...
v
Scott Bigham dsb@cs.duke.edu .___ o&0
http://www.cs.duke.edu/~dsb/ | "Still going..."
Author: No Author
Date: No Date Raw View
Help! I am having trouble printing ASCII test files to a printer (LPT1).
I tried using a system call (system("PRINTIT.BAT"); from stdlib.h ) to
call a batch file to send the print small font command, then print the
file, but the linker doesn't reckognize the system command. I did include
the correct header file (stdlib.h). Can anyone help with either printing a
text file in BC++ 4.02, or the answer to my system call.
thanx
DannyPB@AOL.COM
Author: No Author
Date: No Date Raw View
RWCollectable* foo;
// ...
switch (foo->isA()) {
case CLASS_JOJO:
((Jojo*)foo)->bounceUpAndDown();
break;
// ...
default:
abort();
}
>Also if anyone knows if there is a proposed standard for container
>classes and if so how close Rogue's libs conform.
There is a standard: STL, the [S]tandard [T]emplate [L]ibrary. It is
accepted, not only proposed. For extensive information see
<URL http://www.cs.rpi.edu/~musser/stl.html>.
For the second part of your question: RW Tools.h++ does not conform to STL
at all; it is an entirely different thing (as most libraries are when
compared to STL, for that matter).
You might also want to have a look at OSE, which is available free of
charge at <URL ftp://csis.dit.csiro.au/pub/SEG/> .
OSE is also different from STL, but it is excellent in its own right,
makes good use of templates, efficient, clean design, and the author
Graham Dumpleton provides very good support via the OSE mailing list.
-t
--
Show me the ways to get around the get around.
(Tori Amos, "Yes, Anastasia")
Author: No Author
Date: No Date Raw View
If we take your charter as stated, then there is no need for this newsgroup
moderated or otherwise. If the standard is "forthcoming" then there is
no need for discussion, just reading and compliance. If that is the case,
then this newsgroup will be pretty boring with all vendors posting the
following message:...."We comply with the C++ standard!"....
--
Jim Fleming /|\ Unir Corporation Unir Technology, Inc.
%Techno Cat I / | \ One Naperville Plaza 184 Shuman Blvd. #100
Penn's Landing / | \ Naperville, IL 60563 Naperville, IL 60563
East End, Tortola |____|___\ 1-708-505-5801 1-800-222-UNIR(8647)
British Virgin Islands__|______ 1-708-305-3277 (FAX) 1-708-305-0600
\__/-------\__/ e-mail: jim.fleming@bytes.com
Smooth Sailing on Cruising C+@amarans ftp: 199.3.34.12 <-----stargate----+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\____to the end of the OuterNet_|
Author: No Author
Date: No Date Raw View
>Cfront, however, was sold with UNIX to Novell, or so I hear.
>
>Jason
Have you confirmed that Novell owns Cfront?
--
Jim Fleming /|\ Unir Corporation Unir Technology, Inc.
%Techno Cat I / | \ One Naperville Plaza 184 Shuman Blvd. #100
Penn's Landing / | \ Naperville, IL 60563 Naperville, IL 60563
East End, Tortola |____|___\ 1-708-505-5801 1-800-222-UNIR(8647)
British Virgin Islands__|______ 1-708-305-3277 (FAX) 1-708-305-0600
\__/-------\__/ e-mail: jim.fleming@bytes.com
Smooth Sailing on Cruising C+@amarans ftp: 199.3.34.12 <-----stargate----+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\____to the end of the OuterNet_|
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
8.3.2 References [dcl.ref]
4 A reference shall be
initialized to refer to a valid object or function. In particular,
null references are prohibited; no diagnostic is required.
Jason
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
I can use any C/C++ library (iostream.h, String.h, etc..).
I have read the info pages of Libg++ on String.h and iostream.h
already but I still can not figure out.
Phil
Author: No Author
Date: No Date Raw View
Brett
Author: No Author
Date: No Date Raw View
>Fergus also says that the following byte scrambling is conforming and
>that therefore a garbage-collection proposal must prohibit it:
[...]
>I disagree.
Well, I'm not entirely sure myself anymore. Unfortunately I _still_
don't have a C standard. I've posted a simplified example to
comp.std.c (see the thread "Byte manipulation of pointers").
When a concensus emerges amoung the C standards gurus there, I'll
post a summary here.
>While this code "conforms", its behavior is unspecified
>(implementation-dependent):
>
> A pointer to an object can be explicitly converted to a pointer to
> an object of different type. In general, the results of this are
> unspecified... [5.2.9]
>
>(Has this changed recently?)
Not as far as I know, but I thought converting to "unsigned char *" was
a special case.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: No Author
Date: No Date Raw View
Could you explain this a little further please?
What is the connection with templates?
Satish
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Thanks in advance,
Dan
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
3.6.2 Automatic storage duration [basic.stc.auto]
3 A named automatic object with a constructor or destructor with side
effects may not be destroyed before the end of its block, nor may it
be eliminated even if it appears to be unused.
Note that most complex number classes classes do not have constructors or
destructors with side effects.
Jason
Author: No Author
Date: No Date Raw View
Char is only the smallest integer subtype in C, not necessarily
the type which can contain all elements of the character
set of the machine. Pure Unicode operating systems like
AT&T's Plan 9 use a new library typedef which is called Rune (and
is an unsigned short) for Unicode characters. I don't think, there
are any 16-bit C char compilers or will ever be.
Markus
---
Markus Kuhn, Computer Science student -- University of Erlangen,
Internet Mail: <mskuhn@cip.informatik.uni-erlangen.de> - Germany
WWW Home: <http://wwwcip.informatik.uni-erlangen.de/user/mskuhn>
Author: No Author
Date: No Date Raw View
I have to apologize if this question was asked before.
-- Michael Stal
SIEMENS AG Corporate Research & Development Michael Stal
Dept. ZFE T SE 3 Tel: +49(89)63649380
Otto-Hahn-Ring 6 Fax: +49(89)63640757
D-81739 Munich email: Michael.Stal@zfe.siemens.de
P/O box D-81730 Munich or: michael_stal@omg.org
Germany
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Ordinarily, temporary objects are destroyed as the last step in evalu-
ating the full-expression (_intro.execution_) that (lexically) con-
tains the point where they were created. This is true even if that
evaluation ends in throwing an exception.
Jason
Author: No Author
Date: No Date Raw View
Jason
Author: No Author
Date: No Date Raw View
> To be assured of always having the most accurate version of "Effective C++"
> at your fingertips, I advise you to buy a copy of each printing :-).
;-)
-- Dave
Author: No Author
Date: No Date Raw View
Another area which seems to be little woolly in the standard are the
assignment operators. Now an assignment can be approximated by 3 steps:
a. calculate the address of the LHS
b. calculate the value of the RHS (and maybe convert to the type of the LHS)
c. store the value calculated in b) at the address calculated in a)
The problem is that the standard makes no distinction between a. and c. so
it misses the fact that c. effectively has to occur after both a. and b.,
(but of course a. and b. can occur in any order). So the assignment operators
should introduce a kind of partial ordering (say half a sequence point!) The
best you can do is refer back to that woolly phrase (at least in terms of
expression evaluation) 'execution sequence'. I can find nothing in the
standard which guarantees that the value of the LHS does not change before
the RHS is completely evaluated, so, coming back to the expression:
i = (i = 2), 3;
(which I take was meant to be):
i = (i = 2, 3);
there appears to be no sequence point between i = 2 and i so this expression
is undefined in much the same way that:
i + (i = 2, 3);
is undefined.
>:: As per the abstract machine semantics, an assignment does require
>:: that its RHS be evaluated before the actual assignment (anything else is
>:: an optimization). If the RHS has no sequence points, then the actual
>:: assignment can occur in parallel with RHS evaluation. If the RHS has a
> sequence
>:: point, then the actual assignment can occur only in parallel with that
>:: part of the RHS after the last sequence point in the RHS side.
I don't believe the standard is worded in these terms or that this can be
deduced from it. 6.3.16 says:
"The side effects of updating the stored value of the left operand shall
occur between the previous and next sequence points"
which pretty much scratches any possible reference to an abstract machine
where the LHS can only be modified after the RHS has been evaluated.
--
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Author: No Author
Date: No Date Raw View
-- garbage collection
Ellis and Detlefs' paper; seems to be available from
ftp.parc.xerox.com in pub/ellis/gc. An implementation is available
from ftp.parc.xerox.com in pub/gc.
-- closures [with dynamic extent]
1988 proceedings of the USENIX C++ conference (you can also check
http://www.idiap.ch/ or ftp.idiap.ch in pub/misc-papers); implemented
in GNU C
-- dynamic typing (not just type identification)
Stroustrup talks about this in his books; several implementations have
been written over the years, even with some compiler support and/or
preprocessing (but not compatible); many of the persistent object
store and RPC codes have to do something similar already.
-- signatures
One of the USENIX C++ proceedings between 1991 and 1993 (inclusive);
implemented in GNU C++
-- [better] runtime error checking
A lot could be done by simply standardizing "safe" alternatives for
all the built-in C++ datatypes (int, float, ...). I think I saw a
paper on this at some point as well as some portable sample
implementation.
Ellis and Detlefs' proposal does this for arrays.
Compiler support for this is quite important, since without, integer
overflow checking and array bounds checking can become rather
expensive. That's why it can't simply stay a library but has to be
picked up by vendors.
-- threads and tasking
This has been used on and off by lots of people; what is needed is
simply some kind of de-facto standard interface.
-- sound replacements for cpp functionality
As I indicated, here, I don't know of any solid proposals or papers
yet; something ought to be done... hygenic macros might be a good
starting point (numerous papers; you might check the scheme and lisp
faq's)
There are also a number of other features that GNU C has provided for
years that are quite handy (e.g., typeof, block expressions, alignof,
variable sized arrays, ...). Check the GNU C/C++ info file.
Other extensions that may be in C++'s future are the numerical, data
parallel, and high-performance computation extensions envisioned by
NCEG (the numerical C extension group). Again, there are several
existing implementations of such extensions in C, and probably
numerous papers, although I haven't followed NCEG recently.
Thomas.
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Kurt
--
| Kurt Watzka Phone : +49-89-2180-2158
| watzka@statistik.uni-muenchen.d400.de
| ua302aa@sunmail.lrz-muenchen.de
Author: No Author
Date: No Date Raw View
ValueType* find( IndexType const& elem , bool makeNew ) ;
This is a non-const function: if makeNew is true, it inserts a new
element if it doesn't find the entry, otherwise, it returns NULL.
And the following functions:
bool
contains( IndexType const& elem ) const
{
return (const_cast< AssocArray* >this)->find( elem , false) != NULL ;
}
The case is more frequent than you imagine, and mutable doesn't help.
--
James Kanze email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
>>With this scheme, map would also have map operations (find, count,
>>lower_bound, upper_bound, equal_range) that take value_type& as an
>>argument.
>
>No, map is provides a one way mapping. A two way mapping is different
>container with a significantly different implentation (and more
>importantly cost).
I never mentioned one way or two way mapping. I'm saying that I'd
like to see map with both operations like:
iterator find(const key_type& x);
and
iterator find(const value_type& x);
>>5. (Ordered) set should not have the type set::iterator. The
>> functions set::find, lower_bound, and upper_bound should return a
>> set::constant_iterator.
>
>I don't how requiring the user to type const_iterator instead
>of iterator would be useful.
Either that or change the definition of iterator in Table 8.
>>There is clearly a contradiction between the X::iterator row of Table
>>8 and the use of set::iterator in Section 9.2.1. set::iterator is a
>>constant_iterator and will therefore point to a const T instead of to
>>a T as required by the table.
>
>Yah, but this is minor.
As I said at the beginning these are a few "rough edges and minor
inconsistencies." I like the spec a lot and am looking forward to
using it.
>>7. Putting compare arguments in associative container constructors
>> eliminates opportunities for inlining comparisons. All members
>> will have to use the run-time stored comparison objects rather than
>> the compile-time-known template argument functions.
>
>This isn't true. Read section 7, Function objects, and examine
>the definition of template less<T>, the default comparision
>object type.
No, this is true. Read the rows on constructors in Table 11. If a
user can place a comparison object at run-time into a container, it
must be the case that that object will be stored and used for
associative containers. The Compare template argument for associative
containers can only be used (consistently) as the default thing to
store in an associative container. It cannot be used (consistently)
for expanding efficient inline code for an associative container.
(Section 7's example with transform is irrelevant to this aspect of
associative container.)
>
>>8. I know the term for the action of Binders as Curry. This could
>> just be my problem, but if not, Curry might at least mentioned in
>> the documentation, if not used in the class name.
>
>Maybe in the paper, but I don't think this is necessary in the standard.
Anything decided here is basically fine with me.
>
>>11. ... However Table 10 explicitly specifies a sequence's a.front(),
>>a.back(), a[n] to return references. This somewhat restricts options
>>for implementing sequences.
>
>This is so you can assign to the return values.
>
>>Demanding that references be returned weighs against sequence-like
>>things that would more naturally return objects on the stack. It is
>>much harder to efficiently use a different internal representation for
>>the stored object (maybe the sequence stores raw data (not object
>>copies) in an array or communicates with an external data store, or
>>whatever).
>
>I think these are outside the scope of STL, but see the
>specialization of vector<bool> which returns object of type
>vector<bool>::reference instead of bool & for these operations.
Thanks. Looks like Table 10 is simply in error. vector<bool> does
just what Table 10 seems to disallow. (So, I think the general issue
is indeed within scope.)
>
>>12. From the text alone, I couldn't deduce anything in particular
>> about what *a=t is required to do. Did I miss something and, if
>> not, is it OK (I tend to think it is OK - but also see comment
>> 13)?
>
>It means exactly what it says, if "a" is a non-input iterator and "t"
>is it's value_type then "*a = t" must work, that is the value of T must
>be copied into the location pointed to by a.
The spec does not *say* that the value of T must be "copied" anywhere.
This may be clear to some readers, but I don't like letting my rough
expectations defining terms for the author. I am pretty sure that
defining = to do most anything including absolutely nothing is
consistent with the spec. I am also pretty sure this is correct. I
would just like to make sure that the word "copy" is only used when it
really is supposed to be and that any connection between "insert" and
"=" should be made explicit.
>See the definition of back_insert_iterator for one implementation, the
>definition of vector<T>::iterator, "typedef T *iterator;", is another.
>
>>Also, Section 12.2.2 states that
>> while (first != last) *result++ = *first++
>>``copies into a range.'' I think this is the only time that the word
>>``copy'' is used with the *a=t construct. This is just to note that
>>the word ``copy'' might not be entirely appropriate.
>
>Copy is the operation being performed here. The values pointed to by first
>are copied to the lvalues pointed to by result.
I think you are letting expectation go farther than the documentation
leads. The *a = t definitions in Tables 3 and 4 make no such
guarantees. (Nor do I suspect should they.)
>>13. Should there be some connnection between *a=t, ``insert a copy of
>> t'' (Table 9), ``inserts t'' (Table 11). Something like:
>> inserting a t1 followed by assigning from a t2 is equivalent to
>> inserting a t2 directly?
>
>The fact that:
>
>seq.insert(a, t1);
>*a = t2
>
>is equivilent to:
>
>seq.insert(a, t2);
>
>seems obvious to me.
Yes, it seems obvious to me too that this should be true. That is why
I'm asking whether it should be a guarantee stated in the spec (that
is what I would like to see so that it is indeed a "fact").
>>14. In Table 11 there are several mentions of ``inserts t.'' Should
>> this read ``inserts a copy of t'' (like Table 9)?
>
>STL doesn't support putting anything but copies of objects in
>containers.
I think you are right. It is just that two phrases are being used.
I'm asking for an explicit clarification on whether they are supposed
to mean the same thing.
>>Table 7: Last line of next to last row -- replace ``then'' with
>>``than.''
>
>No.
What?? Websters: than prep: in comparison with <he is older ~ me>
>>pg 21: This statement seems a bit strong: ``vector is the type of
>>sequence that should be used by default.''
>
>If any container will do then vector is by far the most efficient.
This is no big deal to me, so the large number of words used below
does not mean I attach much significance to the issue.
If default means "this is the one to use when you don't want to use a
list or a deque," then no-problem. The use of "default" still seems
presumptuous: some random user might say that list should be the
default and vector should be used in those really, really few cases
where there are infrequent inserts or deletes in the middle of the
sequence. Using "default" seems to imply some (likely unwarranted)
predisposition on how a library will be used. I was just asking for a
more neutral statement of the same information.
>
>Ross Ridge
>
Thanks again for responding.
Doug
Author: No Author
Date: No Date Raw View
The fact that I have to write an additional class.
With an after clause I do not have to write any extra code.
I also think that if you use smart pointers you have to use
reference counting; that menas extra space and that you pointers
operation are slowed down by the updating of the "count"field.
Besides template instantiation is a pain. (and if you don't use
you have to write more than 1 class; even more boring...)
> What's the overhead, if the constructor and destructor are inline?
>
>>xxx f(......)
>>{
> NewPtr<Foo> p1 = new Foo(...);
> NewPtr<Bar> p2 = new Bar(...);
>> // do whatever you want
>> ....
>>}
As said above, referenxce counting involves space and speed overhead.
Anyway, how can you alway be sure that they are alway inlined? I can't!
Inline is just a suggestion ignored in most of the cases.
>
> --
> Fergus Henderson - fjh@munta.cs.mu.oz.au
Enrico.
Author: No Author
Date: No Date Raw View
Now, I'll bet someone can correct me here, if I got anything wrong.. ;-)
-=Max=-
--
\_ \_ \_\_\_ \_ \_ "Two minds, but with one
\_\_ \_\_ \_ \_ \_ \_ single memory!" - Max
\_ \_ \_ \_ \_ \_ \_ \_
\_ \_ \_ \_\_\_\_\_\_ \_ ========================
\_ \_ \_ \_ \_ \_ | Max Headroom is: |
\_ \_ \_ \_ \_ \_ | media @ netcom.com |
\_ \_ \_ \_ \_ \_ ========================
Author: No Author
Date: No Date Raw View
> If you are not afraid of spending a bit of money ( < $200 ) then I would
> recommend that you look at "Codebase/Codebase++". It is basically a
> library, including source for all of your DBase stuff. It includes a
> Dbase editor etc. and it is portable to DOS/Unix...
Is the new DBase for Windows from Borland the same kind of product?
How do the two products compare on features?
-- Dave
Author: No Author
Date: No Date Raw View
In fact, I would tend to always declare W (and I believe that at least
one person proposed a change in the language to require this). If W
does not have a default constructor, then CW *must* be aware of its
presence, whether it declares it or not, since CW must initialize it.
--
James Kanze email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
2 == (foo) 2
could succeed under your implementation.
Jason
Author: No Author
Date: No Date Raw View
Thus, given:
enum X { a , b , c } ;
This enum requires 2 bits. What should the value of (int)(~a) be? 3?
Or some system dependant value? I suspect that the latter is
preferable, but the constraints on this value must be formulated in
standardese.
--
James Kanze email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
5.0.14 Formal argument AAAA of type BBBB is being passed CCCC
or
Formal argument AAAA of type CCCC in call to BBBB is
being passed DDDD
These two messages indicate that the conversion
required to pass the argument is illegal, but that
C++ 3.0 didn't detect the illegality. Failure to
handle const and volatile properly on pointers is a
major cause of this problem. You can usually correct
this with an explicit cast, but the error is probably
the result of a logic error. Note that passing a value
of type char** to an argument of type const char** is
illegal in both C++ and ANSI C. This is not an error
or oversight in the standard as such assignments open
a hole in the type system and violate const safety.
Author: No Author
Date: No Date Raw View
Same here.
>>> Why?
>>Smart references and cleaner iterators.
And orthogonality with operator->().
> Yes, I understand that but why operator.()?
>There are two other possible solutions I know of:
>
> class X : public Y *y { .. } // Bjarne has tested and rejected
> class X {
> Y *y;
> using *y; // I have suggested
> };
Neither of which (unless I misunderstand them) handle the following
case:
You are writing a templated container class in the shape of an array.
To avoid the possibility of dangling references, your operator[] returns
a proxy class, as described by Coplien and others:
template <class T> class Array {
class ArrayProxy {
// etc.
};
public:
ArrayProxy operator [] (int);
// etc.
};
Since T might be a pointer type, you add the member function
Array<T>::ArrayProxy::operator->(). But what if T is a class type?
struct fred {void member_fn();};
void f(Array<fred> &A)
{
A[0].member_fn(); // "error: no member function
// Array<fred>::ArrayProxy::member_fn()"
}
The obvious thing to do here is overload operator.() in the same way as
operator->().
-sbigham
--
Scott Bigham | The opinions expressed above are
dsb@cs.duke.edu | (c) 1994 Hacker Ltd. and cannot be
| copied or distributed without a
| Darn Good Reason(tm).
Author: No Author
Date: No Date Raw View
"Automatic, register, static and external variables may be initialized by
arbitrary expressions involving constants and previously declared variables
and functions."
I think that it should work and give you the same results on all compilers.
However, whether it is evaluated at compile-time or run-time may depend on the
smarts of the compiler.
Author: No Author
Date: No Date Raw View
From Base with love...
Author: No Author
Date: No Date Raw View
From Derived with love...
Author: No Author
Date: No Date Raw View
From Base with love...
Author: No Author
Date: No Date Raw View
it's obvious that the derived's func didn't override the func
of base if we accessed those func's by a pointer.
but if we change it to:
//same
class Base {
public:
virtual void func() { cout<<"From Base with love...\n"<<flush;
}
//func() IS virtual
};
//same
the output,
Author: No Author
Date: No Date Raw View
From Base with love...
Author: No Author
Date: No Date Raw View
From Derived with love...
Author: No Author
Date: No Date Raw View
From Base with love...
Author: No Author
Date: No Date Raw View
seems right.
I don't know what exactly legal or illegal mean here, but I know
if I want my result correct, I got to use virtual.
PS. I am using CC on a SunOS 4.1.1 sparc station, some other
compiler or OS would give different results?
QD
Author: No Author
Date: No Date Raw View
"Basically, the linker is run, and if some template function
instantiations are missing, the compiler is invoked to produce the missing
object code from the template source. This process is repeated until
all templates have been instantiated. Templates and argument-type
definitions are (when needed) found based on a file-naming convention.
Where needed, this convention is supplemented by a user-supplied directory
file that maps template and class names to the files that contain their
definitions. ... This strategy often works very well, but in some contexts
three very annoying problems were discovered: ..."
These are Strostrup's own words.
My main point is not linking per se, it's the problems of assembling
a collection of program parts into an entire program. C++ suffers at
both ends in this area; the "include" file mechanism is limiting for
reasons that have been recently discussed here, and the reliance on
dumb linkers creates yet another set of problems.
I don't blame Bjarne for this; the early versions of C++ were
more limited in scope and didn't create as many problems in these areas.
But with all the features currently in the language, the task of
putting the pieces together requires more powerful support than what we
have now.
This can't really be put off as an "implementation issue". Most
of the problems are implicit in the language design, and can't be fixed
cleanly without some language changes.
John Nagle
Author: No Author
Date: No Date Raw View
"Information hiding" does not hide data from data objects. It hides
information from *programmers*, so they need not be bothered by it.
Information hiding also helps to keep the cooks-to-soup ratio under
control. It often makes perfect sense to have member functions inspect
the internal data of objects other than the one pointed to by "this".
Structural sharing schemes would be impossible if member
functions were not allowed to inspect and modify the representations
of other objects of the same class. (Think reference-counting.)
-- Dave
Author: No Author
Date: No Date Raw View
I didn't know that. Hmmm... I can see it now...
Customer: Your new software deleted my disk drive and set my pants on fire!
Me: Yeah, but it reads like a dream!
Author: No Author
Date: No Date Raw View
6. How to Design Your Own PC
You don't have to be an engineer to design and build the PC of your
dreams. This plain English video shows you how to figure out the
PC design that is best for you, how to specify components, how to
make sure they'll work together, and where to buy them. You'll end
up with a top quality system that will save you money.
7. How to Build Your Own PC
Once you've designed your PC, we'll show you how to build it. The
actual process will take you only a few hours. Using an easy-to-
understand method, we'll show you how to inspect, install and test
components. Includes tips and tricks from computer production
experts. The technical skills can be easily mastered by almost
anyone, and you probably already own most of the tools you would
need.
8. How to Increase Your Computer's Memory
This plain English video shows you how to determine whether your
computer memory can be increased, and how to do the job correctly,
one step at a time. You'll learn about industry-wide standards for
memory, how to configure additional RAM and cache, how and where to
buy RAM chips, and three ways to eliminate low-quality RAM chips.
Covers all phases of the process from opening your computer, to
testing your memory. Includes discussions on how to ensure your
DOS set-up is able to access all available memory, and how to use
various memory management software applications.
9. How to Use MS-Windows 3.1
This powerful graphical user interface can help you work smarter
and faster, but the manual and the online tutorial that come with
Windows leave many questions unanswered. This plain English, step-
by-step video will show you how to install Windows on your computer
and set it up to get optimum performance.
10. How to Find a Job in the Information Age
A PC can give you an incredible advantage when you're searching for
a new job -- or even a new career. But you have to know just how
it can help you. In this video, an experienced employment
counselor will show you how to tap the power in your PC to find job
leads, create a winning resume and customized cover letters, tap
into databases and find bulletin boards that will lead you to job
openings, and use online services to research potential employers.
11. How to Install a Sound Card in Your Computer
Here's how to add incredible stereo sound to your computer with
step-by-step help. In plain English, you'll learn how to determine
if your computer can support a sound card, how and where to buy a
high-quality sound card. How to open your computer, and install
and test the sound card.
12. How to Install a CD-ROM Drive in Your Computer
Using simple tools, this plain English video shows you how to
install a CD-ROM Drive in your computer. You'll learn how to make
sure your computer can support a CD-ROM drive -- and what to do if
it can't. Covers internal vs. external drives, how and where to
buy a high quality CD-ROM drive, what you need to know about
differing industry standards, preparing the drive bay, testing and
trouble-shooting. Covers SCSI and IDE.
13. How to Fix the Most Common Computer Problems
Your computer serviceman may not want you to know this, but all you
need is the know-how you'll get from this video, simple tools, and
easily-obtainable diagnostic software -- and you can fix most
common problems you'll ever encounter with a PC.
14. What to Do When a Virus Strikes Your Computer
Viruses can come from almost anywhere: a colleague or friend's
disks, a network, a bulletin board, even commercial software. If
you ignore the first warning signs, a virus can wipe out your data
and permanently damage your computer's memory. In plain English,
this video will tell you how to scan disks for viruses, how to
check downloaded files from bulletin boards, how to set up a virus
prevention program for your home or office computer, and how and
where to buy the best anti-virus software. We'll also cover the
pros and cons of the antivirus software in DOS 6.X and Windows 3.X,
how to use antivirus software, and more.
15. How Your PC Works: Inside the Case
Here's a down-to-earth explanation of how your PC actually
processes information, and what really goes on inside the case.
You'll get a guided tour of the insides of a PC, learn about how
the various components work and how they communicate with each
other, and get a clear explanation of technical terms. A must for
anyone who wants to really understand how to program, use and
repair a PC.
16. How to Create Config.Sys, Autoexec.Bat and Batch Files
These basic files can make it much easier to use your computer --
or cause incredible headaches if they are not written properly for
your particular software and peripherals. Now you don't have to be
at the mercy of murky tech manuals, because we'll show you how to
create files that work for your system -- step-by-step, in plain
English. You'll learn how to write, modify and test Autoexec.Bat
and Config.Sys files; and how to create batch files.
17. How to Add a Modem or Faxmodem to Your Computer
Here's the easy way to add a modem or faxmodem to your computer,
with step-by-step guidance from this plain English video. You'll
learn how to determine if your computer can support a modem or
faxmodem, and what to do if it can't, how to choose and buy the
best modem or faxmodem, how to open your computer, and install the
modem or faxmodem, how to test it, how to quickly eliminate common
problems, and how to set your modem or faxmodem correctly.
18. How to Make Money at Home With Your Computer
The information age is opening up incredible new opportunities for
PC owners to make undreamed of money, using skills and knowledge
you may already have! Here's inside information on the ten most
promising telecommuting jobs and 12 small businesses you can run
right from your home, using your PC. Includes profiles of PC
owners who are actually running PC-based home businesses.
19. The Super-Highway Roadmap
This is your guide to where to go and what to see. You can make
incredible contacts and gather powerful, valuable information on
the Internet, but the problem is that most people can't begin to
imagine the potential of something that seems so abstract. This
plain English video will introduce you to the Internet, and make
these opportunities concrete. Includes interviews with 7 people
who did the impossible by gathering information and making contacts
on the Internet.
20. How to Upgrade and Repair Your PC I: Basic
This is the video your repairman doesn't want you to know about!
Since the components of most PCs are highly modular, PC repair is
easier than you think. Just pinpoint the problem component, unplug
it, remove a few screws, replace it, and presto! You're in business
again. This step-by-step video shows you how to pinpoint problems
and replace your PC's components, using ordinary household tools.
21. How to Upgrade and Repair Your PC II: Multimedia
Here's how to save big money on a PC with all the latest multimedia
peripherals. You learn how to determine if your PC can be
upgraded, how to upgrade your video card and bus, and how to add a
CD-ROM drive, sound card, video accelerator, and more. Presented
in plain English. The procedures you'll learn require ordinary
household tools -- nothing fancy!
22. Plain English Guide to DOS 6+.
The powerful sub-programs buried deep within DOS 6.0 and higher can
help you work smarter and faster, but the manual and the online
tutorial that come with DOS leave many questions unanswered. This
plain English, step-by-step video will show you how to install DOS
on your computer and set it up to get optimum performance. In
addition to DOS commands, you'll learn how to use the shell,
defragmentation, scan and antivirus programs that come with DOS.
23. Home Financial Management on a PC.
Your computer can help you create and manage a budget, keep track
of your credit card accounts, handle your tax deductions, and
reconcile your bank accounts. But that's not all! You can also
determine whether you should pay down your mortgage, finance a new
car or pay cash, buy or rent your home, and how much you'll need
for retirement. The financial information your computer can give
you might mean the difference between just getting by and a very
comfortable lifestyle -- if you ask the right questions and use
your PC to develop a financial strategy.
24. The Online Bulletin Board Guide
Bulletin boards can be the on-ramps to the Information Super
Highway -- if you know how to access and use them. This step-by-
step guide shows you how to find bulletin boards, set-up your
modem, log on, find out what they have to offer, find bulletin
board users who share your interests, search for information, and
upload and download files.
Thank you.
Author: No Author
Date: No Date Raw View
> I regret that the C++ standardization committee decided that saving
> three characters was worth more than giving this type the same name as
> in many other commonly used programming languages, e.g., Pascal,
> Modula-2 and Ada. We did in fact vote on "bool" vs. "boolean".
>
>
> -- Dag
My candidates would have been "Boole" and "Boolean".
At least it should be capitalized, don't you think? It is a proper name,
after all. Show a little respect.
- Dave
Author: No Author
Date: No Date Raw View
> There is another aspect to the problem, of course, and that is the
> efficiency of generated code. If the compiler can establish by
> compile- and link-time checking that a function cannot exit by
> exception throw, then the code to invoke that function can have fewer
> instructions and take less time. If "default=any", then by default
> function calls will include exception-handling code.
I don't know anything about how exceptions are being implemented, but
I would have thought that the overhead would be isolated in the called
function. Requiring different calling conventions for functions
that can throw exceptions would create a really big mess, wouldn't it?
In any case, I don't see what the exception signature has to
do with the compiler unless the compiler can perform (static) signature
checking. The signatute is simply an assertion by the programmer. There is
no existing compiler I know of that is capable of checking that assertion.
If it can not check it, it must generate code that is capable of handling
the situation when the signature is violated -- so far as that is possible,
which is not nearly far enough, IMHO.
> If on the
> other hand "default=none", then by default functions are assumed to
> exit normally, and the calls to them can be made simpler and faster.
My guess is that the large majority of functions will be "throws any",
and that's as it should be. Certainly any routine that calls operator new,
either directly or indirectly will have the signature "throws any".
Of the few that do not throw any, the large majority will be "throws none".
It is hard to come up with examples of functions that would "throw some".
Author: No Author
Date: No Date Raw View
That scenario is a myth, invented by movie makers, or maybe pulp fiction
writers. I invariably get irritated when I seen the scenario played out
on screen. If you think about it a bit you will see that such a rule could
not possibly work. The person with the most money would win every hand.
(Lawsuits may be like that, but there are generally no sheriffs with pistols
*forcing* you to play in the poker game -- and that's a big difference.)
Arbitrarily perculiar things may happen in small home games, but
all real poker games, public or private, require that a player declare
before a hand begins how much money "plays", which by default is
the amount of chips in his stack.
If he intends to buy more, he says, "Money plays," and puts the money for
the chips on the table *before* the start of the hand. The common
"table stakes" rule says that no chips or money may be removed from the
table or passed from one player's stack to another during a session; You must
either put your winnings at risk or leave the game. In games that do
not have the table stakes rule, you are supposed to announce when you
"rat-hole" winnings, but that rule is sometimes abused.
In any case, if you bet your last chip, you declare "all in", and a new pot
is started in which you have no financial interest. You do not lose
interest in the pot you have already bet into. Because side pots can be a
little disruptive, there are usually limits on how few chips you can buy.
A common rule is that a player is only allowed one "short buy", (less
than some arbitrary minimum), per session.
In no case is a player ever given the option of "grabbing his butt",
(buying more chips with money from his wallet), or going all-in. An option
like that would give short money on the table with money in the pocket
a gigantic advantage -- but not as large as the mythical "If you
can't call, you lose" rule.
Author: No Author
Date: No Date Raw View
Neither.
Try,
const float pi = 3.142;
or better yet,
const float pi = 3.1415926536;
I could go on and on.
Dave
djones@silly-math-triva
Author: No Author
Date: No Date Raw View
Jan.
Author: No Author
Date: No Date Raw View
[...]
This problem is trivially solved with a comment, careful code
organization (i.e., grouping all of your "guests" together")
and a bit of self discipline and/or code-reviews.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I don't know the full story behind the alleged Microsoft patent,
but it is a fact that you can't patent something that has
already existed, aka "prior art"; another way: patents can not
be retroactive.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I *know* that the deprecation of old-style casts was rejected,
but what's that got to do with deprecation of auto float->int
conversion:
float f = 1.0;
int i = f; // deprecated or not?
THERE IS NO EXPLICIT CAST INVOLVED HERE!!
Now, would you please answer my original question?
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
> I'll try an example. Suppose F calls G calls H, and their signatures
> claim that they throw f, g, and h, respectively. I code G something
> like this:
>
> G() throw (g) {
> try { H(); } catch (h) { ... }
> }
>
> This should compile with no warnings, right? I would like it very much
> that compilation with no warnings is a guarantee that G will only throw
> "g", or else "fail".
My first impulse is to say, if it were up to me, I would insist that the
compilation of G() with no *error* -- (Warnings are too weak.) -- would
guarantee that G will throw no exception other than "g", period. But having
thought it over little, I can see a use for a truly awful exception,
(a "TAE"?), which is thrown only in those places that are supposed to be
unreachable, or thrown by the operating system or runtime support when it
detects a hardware malfunction, memory or corruption, or something really
dreadful like that. Something that says, "Try to get into a safe state, and
then get us the hell out of this mess without killing anyone."
Is there such a proposal on the board? If so, might I suggest the
traditional "InternalError" as the name, rather than "fail",
which could be interpretted to mean simply that a function did not
accomplish its main task? (Would SEGV be a derived class of "fail"?)
> Now, consider H:
>
> H() throw (h) {
> throw (i); // An exceptional exception.
> }
>
> With iron-clad static checking, this won't compile, but we don't have
> iron-clad static checking. So, all we get is a warning.
Do we even get a warning? If the compiler can issue a warning, why can't it
issue an error message? (Of course "fail" would be exempt, if that is
declared the standard "gosh-awful" exception.)
> So, all we get is a warning. And we ignore it.
Pardon me, but *WE* don't. I would never ignore a warning like that. I would
get to the root of it, and I would expect any programmer who produces
commercial product to do so, invariably. No exceptions (so to speak), and
no excuses.
> So, now, what exceptions can propagate out of G? If we don't dynamically
> turn this "i" into "fail", then H (and G) will throw "i", contrary to what
> we wanted to be true. This also confines the error to near its origin,
> namely "H" [...]
> So, dynamic checking is there to protect you from sloppy coding (speaking
> broadly and judgementally).
You said it, not me. I am concerned that many programmers will think that
the exception signatures provide safety. They may think code that
uses exception signatures is, by virtue of that use, not sloppy coding.
That to me seems like a very real danger. Can new programmers be relied on
to know that no product should ever be shipped with dynamic checking
turned on? Should they be expected to know that an exception signature
is *not* a promise that a routine will not throw other exceptions, but only
a promise that if it does throw other exceptions, something will happen that is
completely unacceptable in shipped product? Does the benefit, as you
described it, warrant the danger?
In my opinion, the answer is no. But you have demonstrated that in certain
situations, using debugging systems that may prove to be typical, dynamic
checking may expedite somewhat finding the source of a bug once it
manifests itself. I understand the example, and agree that it answers
my challenge.
I was trying to justify exception signatures for a completely different,
and much more important goal: shipping correct code. I have never seen
a bug so obscure and unrepeatable that the cost of fixing it was on the
same scale as the harm usually done when even an easily repaired bug is
discovered by a customer. I think I can argue that strict statically checked
signatures could expedite writing demonstrably correctly code. It could
obviate the need for "just-in-case" try/catch blocks.
> ... (And one reason I believe that default=none is better
> is because it centralizes the obnoxious work of getting the proper
> signatures on things -- otherwise, you, me, and every other
> user-of-exception-handling-who-dislikes-dynamic-checking will do the work
> all by ourselves, over and over again, making stupid little errors along the
> way.)
Hmmm. I don't see it. I think "throws any" should be the signature of
the large majority of functions, and should be the default, but I am
open to counter-arguments.
Here's the way I see it:
Unless the language definition is changed in a very disruptive way,
if default==none, then any existing constructor or function that calls
operator new, either directly or indirectly, is immediately broken, because
set_new_handler() can be used to modify the behavior of operator new
in arbitrary ways. It would be a major headache to add throws(any)
exception signatures to virtually every routine in existence.
But even if there were no code already written, default=any whould
still seem to be the choice, because the large majority of
code should not *need* to require that the the routines it calls have
restrictive throw signatures. Instead they should be written in the
exception-safe "allocation is initialization" discipline. Those that
can deal with some exceptions should generally catch those, but pass
any others through.
> Does this clarify things somewhat?
Somewhat. I understand the first part. I am still not clear on why you prefer
default = none.
Best wishes,
Dave J.
Author: No Author
Date: No Date Raw View
Mucking with private data will most likely violate the integrity
of an object; the "guest" proposal has no such benefit.
Furthermore, "private" and "protected" parts are aimed at users of
a class whom the class author has no control over; "guest" is
aimed at the author him/herself. I would hope that s/he has
control in that case.
Seriously: a comment and sensible grouping are all that is
needed. The proposal just isn't worth it. Besides, we both
know it hasn't got any chance of being taken seriously and even
less of actually getting passed. Can we talk about something
else now?
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
And what's that got to do with anything?
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
> Isn't this an impossible goal? How can your code remain correct if some code
> you do not control has changed? If you wish to qualify it by `changes only
> involving the exception signatures' you may have a point, but I would argue
> that it is still an unrealistic goal.
Yes, if the rules change, you may have to change the client code.
With static checking, the compiler will tell you the rules have changed.
With dynamic checking, the incompatiblily may go undetected until the
product is in use.
> The real goal should be `write correct
> code which changes as little as possible' or something of that nature. The
> point is that if it _needs_ to be changed you damn well _want_ to change it.
Precisely.
> ... eventually _someone_ should handle the exception - otherwise the program
> crashes anyway.
True. The problem with the dynamic checking scheme is that a function may
crash the program even though there is an exception handler active on the
calling stack that is prepared to deal with the exception.
> If you are writing critical code, that an exception _is_
> handled and _where_ is very important, and checked signatures give you that.
_Statically_ checked signatures would.
>> Ah ha. I've got it. The only time that the signature helps is when
>> a procedure can not safely abort and pass exceptions through. THAT'S IT!
>> It helps when the calling procedure must deal with all exceptions
>> right there on the spot. In that case, and that case only, it may help
>> to have an exhaustive list of all possible exceptions.
>
> Exactly. And such procedures are _necessary_ in critical software.
Okay, good. We agree. I just don't see how dynamically checked signatures
solve the problem, or even help very much.
> Or critical code that is not allowed to fail. In which case you need to
> handle each and every error and be certain you have done so.
Precisely. Dynamic checking does not guarantee that it will not throw
other exceptions, only that the program will crash if it does. -- Not
very good behavior in "critical" code.
> For a well defined class of programs, those that `are not
> allowed to fail'. In such a case both statically checked signatures and the
> default=any make a lot of sense (because third party libraries may not be
> checked, and will not have signatures, and may throw anything at all).
We agree!
>
>> 4. Dynamically checked signatures are useless and dangerous.
>
> Definitely.
>
Hooray!
Author: No Author
Date: No Date Raw View
> Given this [difficulty with templates], the compromise of run-time checking
> of exception signatures appears more reasonable to me now than it did at
> first sight.
What does it accomplish? No one has yet to show me what dynamically
checked signatures are good for. Somebody give me a hint. I am at a
complete loss as to how to justify them.
- Dave
Author: No Author
Date: No Date Raw View
Given the fact that the C++ compiler itself is free (and eager) to make
casts that the programmer did not indicate - that he might not even be
aware are possible - this seems like a pretty bad situation. To be safe,
it seems to me that the committee should stipulate that the temp object
(obj1 + obj2) must survive during the intire call to foo().
- Dave
Author: No Author
Date: No Date Raw View
It's not a class; it's a fundamental type just like int.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
The idea of a default exception list which is appended to the exception
signature seems to me to be a useful idea. Some thoughts:
1. I think it would be better to use a union operation rather than append.
The union operation should be defined so as to automatically recognise
when base-exception and derived-exception can be unified.
2. Rather than have this a just a feature for compatability, it is worth
considering the idea of being able to set this default list for a given
namespace or object (I'm not sure which is more appropriate - My first
thought was 'object', but then I realised that global scope means
global namespace, not ultimate base object - and our default xmsg list
has global scope)
2a. To enable simple implementation of fire-walling, one should be able to
place a default exception handler around the scope of any such default
list. (similar to set_unexpected, but it is used so that unexpected
isn't needed in that situation). This implies that the usage of the
deafult list is dependent on where the function is called from - when a
function is called from inside the list's scope then the list is implied.
When its called from outside its not unless an exception is explicitly
within the signature; if this is not the case then the default exception
handler would be called. This behaviour may be undesirable.
3. It should be possible to explicitly reject the default list for a given
function if required.
4. Static checking is still a must in my opinion - even if only to generate
warnings.
Please feel free to comment - and tell me these ideas are unnecessary,
unworkable, undesirable, ill-considered, etc.
--
David P. Whipp. <whipp@roborough.gpsemi.com>
G.E.C. Plessey -------------------------------------------------------
Semiconductors Due to transcription and transmission errors, the views
expressed here may not reflect even my own opinions!
Author: No Author
Date: No Date Raw View
>
> Evidently, many people (myself included) still believe that the costs
> associated with adding static exception checking are significantly
> larger than any potential benefit.
>
> Thomas.
That may well be the case. But many people, (myself included) now believe
that dynamaic checking is totally useless at best and can introduce horrible,
nonrepeatable bugs at worst. I think one can make a very good case for
ditching exception signatures all together. I read an article that claimed
they were only proposed in the first place because of some bullying by
compiler vendors. Why they would want to make more work for themselves
is a puzzlement.
I think a very good intermediate solution would be to implement only
two signatures: throws-any (default), and throws-none. I predict that after
people figure out what the signatures are actually good for, then only
those two signatures will typically be used anyway. The throws-none could be
checked (statically) very easily.
-- Dave
Author: No Author
Date: No Date Raw View
> ... users should NOT be forced to use exception signatures if they
> don't want to.
Hear! Hear!
> I'm certainly not convinced that I will want to use them.
I'm giving a talk on exceptions for my company on the 25th. I will recommend
in no uncertain terms that until such time as exception signatures are checked
statically, they will be strictly outlawed in the company coding standard.
I will also recommend that we not buy third party software that uses
exception signatures, unless it is compiled with a compiler that does
full static checking.
-- Dave
Author: No Author
Date: No Date Raw View
Q4: Whats this about a new "bool" type?
A4: The committee voted in San Jose to introduce a new type "bool"
as a standard type. Bool is addressable, you can have a pointer
to a bool. Bool is not an arithmetic type, but it converts
by a standard conversion to all arithmetic types.
Bool has two values, "true" and "false".
Bool is the type returned by all comparison operations, and
the || and && operators. Bool is the type required for
&& and || and in an if(), while(), do..while() and for()
statement.
Arithmetic types convert automatically to bool, 0 is false,
everything else is true. Pointers and pointer to members also
convert to bool by the same rules.
The expression
++b
is supported but deprecated for bool, so as not to break
too much code relying on the common idiom
int found=0;
while(!found) { ... if(..)++found; }
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: No Author
Date: No Date Raw View
> As to why compiler vendors want more work or not, there are many ways
> to view this:
>
> 1. you are drastically overestimating the relative difficulty of implementing
> exceptions ...
I think I might have some idea of the amount of work involved. I have written
a commercial compiler from scratch. Okay, it is only Pascal, but it
works real good.
> 2. compiler writers are also programmers. Some of us have used exception
> handling in the past, and think it is a very good idea
So have I, and so do I. I've always had to "roll my own" exception
mechansim. This is my first compiler that supports the concept. Oh happy day!
We have no disagreement so far.
> .. Your intermediate solution [throws-all or throws-none] is
> completely unacceptable.
Could you please say a few words to justify that opinion? I am genuinely
interested.
I think the "interdemiate solution" might be very useful. The way I see it,
an exception signature is a promise not to throw certain exceptions (those
not listed). I ask myself the question, when is that promise useful?
Answer: When two conditions are met. 1) When I am writing code that can
not easily be made exception-safe, and 2) When I can trust the promise.
The promise of "throws none" is the most useful promise, because it is the
strictest. It puts the most constraint on the function I am attempting to
use. If I must make provisions for even one exception, it will probably
not be too much more work to add code to handle all others. Regardless of
the promise, throws-none or throws-some, static checking is the only way
to make the promise trustworthy. Dynamic checking says, "If I can not keep
the promise, I will crash your program." Thanks a lot.
Do you disagree? If so, please explain. A programming example would be
very much appreciated.
> Listen to people who
> have programmed in languages with exception-handling in them
> (instead of people who have not).
Although I do respect experience, I'll listen to anyone. I started
programming for a living in 1971, but I still learn something every day,
sometimes from people far less experienced. I am not interested in arguments
that appeal to authority and experience per se. Let's talk about programming
and programs, not credentials. If someone wants to illustrate a point
from experience, fine.
> Even with default=any, signatures are useful, because you
> can still program in a fully annotated style
Default=any is obviously the only way to go. But I am not clear on
what you mean by being "useful" as annotation. How does it help if it
is dynamically checked? How is it better than a comment? Again, an
example of a case where dynamically checked exception signatures
are helpful would be greatly appreciated. I honestly do not see any
use whatsoever for exception signatures that are checked at runtime. None.
Zip! All I see is the danger of very nasty program failures. Please explain
the benefits. Perhaps an example?
> What do you do with all your unadorned code when
> you finally get a compiler with static checking?
It should still compile and run just as is, with no modifications.
Why wouldn't it?
-- Dave
Author: No Author
Date: No Date Raw View
Obviously "obvious" is a relative term. :-)
As I am scheduled to give a talk on the subject of exceptions a few days
hense, I thought I better get a handle on the issue. It was not at all
obvious what all the brouhaha was about. So, as I sometimes
do when confronted with such problems, I picked a side at random and tried
to defend it. I happened to pick the dynamic checking side. (I rather
expected it would win my little thought experiment, because it has been
chosen by my C++ vendor.)
Well, I couldn't defend it. I was able to smash my every attempt to defend it.
In the end, I could find absolutely no benefit that could stand up to
scrutiny. Dynamic checking simply does not do anything useful. Nothing.
Against that was the fact that the introduction of a new entry
in the throw signature by a software vendor or another programmer could cause
a correct program to crash "unexpected"ly, and the case against dynamic
checking was solid. Next case.
I tried defending static checking. Surprisingly (at least to
me), I could not make much of a case for it either, but at least it was
safe. I asked myself the question, "If I am a software developer seeking
to write correct code that will stay correct in the face of implementation
changes in the code I do not control, when does it help me to see a
throw-signature on a function that I want to use?"
It does not help me when I am prepared to deal with the listed exceptions but
no others, because in that case I could deal with a throw-any function
by just catching the exceptions that I am interested in, and passing the
others down the line. That is part and parcel of the "resource allocation is
initialization" discipline: A procedure very often does not need to know
what exception is thrown. Typically it just cleans up its local frame
(automatically), and returns. Sometimes it deals with certain exceptions
that it can deal with, but passes the others through.
Ah ha. I've got it. The only time that the signature helps is when
a procedure can not safely abort and pass exceptions through. THAT'S IT!
It helps when the calling procedure must deal with all exceptions
right there on the spot. In that case, and that case only, it may help
to have an exhaustive list of all possible exceptions.
Put another way, exception signatures are of use to programmers who are writing
*exception unsafe* code -- code that does not follow the resource allocation
is initialization discipline. In well designed programs, such code is
generally confined to the statement blocks of a constructors.
If I have code like that on my hands, the throw signature narrows my task
for me. I may be able to savely leave the code in its "exception unsafe"
condition, particularly if the promise is that NO exception can be thrown
by the function. At worst, I will have to re-write it to handle only
particular, well defined exceptional conditions. If the promise I am
depending on to make the code safe is later broken, the compiler will
let me know, rather than simply putting an unreported, unexpoloded
bomb into my program.
Now it is at last obvious (to me):
1. Having no exception signatures would be perfectly acceptable.
2. Statically checked signatures that are part of a function's external type
would occasionally prove useful if understood and used correctly.
3. Two types of functions, "throw-any" and "throw-none", would accomplish
almost as much as full signatures.
4. Dynamically checked signatures are useless and dangerous. They
"keep their promises" in a weird kind of way. It is as if I were
a sax player who has promised not to be late for a gig. When
I discover that I will not be able to make it, I simply
burn down the dance hall. My perfect defense will be, I was not late
for the gig, because there *was* no gig! The offending function says,
I didn't throw the program an unexpected exception. There *was* no program!
Author: No Author
Date: No Date Raw View
> I agree completely and will propose this extension to
> the language if no one else does first.
I received email from Bjarne indicating that he has already made the proposal
to the standards committee. Wish us luck.
Author: No Author
Date: No Date Raw View
> Theoretical arguments aren't very convincing, at least to me, so here
> is a pragmatic one.
>
> Suppose you're using a library from vendor X that in turn uses a library from
> vendor Y. The Y library has I/O routines, which may potentially throw
> I/O error exceptions. Suppose, for example, that the Y library contains
>
> extern void write (Device, Buffer) throw (IOerror);
>
> Now suppose that vendor Y adds networking capabilities to the Y library.
> That means that if you apply `write' to a network device, it might now
> raise a network error:
>
> extern void write (Device, Buffer) throw (Networkerror, IOerror);
If I do not need to support networked devices right off, the new
behavior of write() is only a future threat.
If I need the new functionality, I am in a mess. I can not know that the
X software is written so that it can tolerate the Networkerror. Very probably
it can not. I have a lot of telephone calls to make. This is how I make
my living.
>
> Now, this happens only if you're using a network device. In that sense,
> it is strictly an upward compatible change.
I don't understand how this is "upward compatible" in any sense.
I have purchased a library that has a "write" routine in it. That routine
comes with a "contract" (its declaration) which promises that it only throws
the exception IOerror. My software (possibly purchased from a third party,
vendor X) may depend on the once promised behavior; I don't know.
Now the library vendor adds support for a new kind of device, and
simultaneously breaks the contract. I can use the new library
with my old software only if I do not use any of the new devices. To use the
new devices, I must rewrite my software, or verify that it does not need
rewriting. However, the compiler does not tell me that. Unless I have an
extraordinary QA department, the problem will be reported to me by a
customer, who wants to know, "What does 'Unexpected exception thrown' mean?"
He wants to know it *loud*.
But let's say I get lucky, and that the library vendor puts a warning
in the release notes, and that I do read it. If I do not need to add the new
device right away, I may defer updating the application software, inviting
disaster later when we do support the new device. But let's say I do
realize that I must change my software, and that I should probably change it
right away. Now I have to change my software, which is the same
situation I would have been in if the compiler had simply told me to change
it in the first place.
> Yet if exceptions are statically
> checked, there is no way to make this an upward compatible change to the
> Y library: adding Networkerror to the throw list will break the library
> from vendor X.
It very likely breaks it in either case. It may be okay for a while
if vendor X's library only supports old devices, but it is a ticking
bomb in any case.
> It was scenes like this that argued convincingly that checking exception
> specifications must not be done at compile time.
You are convinced too easily. You should try being a stubbord
old fart like me. :-)
> In effect, it would mean
> that the exceptions thrown by a function must never change once that function
> has been defined.
That's exactly what it means, and what it should mean. The signature is
a *promise* that should not be broken lightly. If it's not a promise, then
put it inside a comment and put a question mark next to it.
Dave
P.s.
Isn't there a better way to declare the exception type in the first
place? Shouldn't the exception type be defined as a base type so that it
can be extended by derivation?
Author: No Author
Date: No Date Raw View
'i' is a vector of integer. Vectors are *not* pointers, never
have been in either K&R C, ANSI C, or C++. A vector "decays"
into a constant pointer to the first element in all contexts
except as an argument to sizeof.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
That's ok, I can't think of any reason for it. If you expect
some proposal to be taken seriously, then you have to at least
explain the semantics of it.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
1) C++ structs that "look like" C structs must map to C structs,
including const data members, for compatibility. (If a struct is
defined with the word "class", or has a member function, base class,
or access specifier then is it permitted to deviate from C mapping?)
2) The address of different instances of a const data member must
compare different. And the address can't be "spoofed": dereferencing
that address must of course yield the true data value. (The compiler
*could* try to determine that the address can "never" be taken/compared/
dereferenced, but doing so would be hard work.)
But at least, even if the memory must be allocated, I can see
nothing in the ARM (or in C compatibility) that would prevent the
compiler from optimizing away, if it chose, the fetch of a
guaranteed-the-same member value from that always-allocated memory.
garry
--
Garry Wiegand --- garry@ithaca.com --- Ithaca Software, Alameda, California
Author: No Author
Date: No Date Raw View
>>>>UPDATED 9/93
You can get a paper copy by sending a request to:
Standards Secretariat
CBEMA/X3
1250 I Street NW
Suite 200
Washington, DC 20005
Ask for the latest version of `Working Paper for Draft Proposed American
National Standard for Information Systems -- Programming Language C++'.
The last known phone number: 202-626-5738. The last known price is $25.
==============================================================================
Jamshid Afshar
jamshid@ses.com
Author: No Author
Date: No Date Raw View
>However, if I try to define it twice (by say declaring it in a .H file, and
>including the .H file twice), cfront 3.0.2 gives a multiply-definded error.
Cfront is correct. You can't initialize A::x in more than one
compilation unit.
The way to achieve what you want is to use an enum constant instead:
class A {
public:
enum { x = 30 };
};
--
Fergus Henderson - fjh@munta.cs.mu.OZ.AU
Author: No Author
Date: No Date Raw View
r.14.8:
Initializers can be specified for static members of template classes.
Given
template <class T> class X {
static T s;
//
};
The static member s can be defined for a template class X<int> like this:
int X<int>::s = 997;
Further, one can specify a default value for X<T>::s in general like this:
template <class T> T X<T>::s = 2;
That is, if no initializer is given for a template class X<Y>, its initial
value will default to 2.
Jason
Author: No Author
Date: No Date Raw View
I think Jason has uncovered something here. I find that a different
version of his program (see below) sends our xlC compiler into an
infinite loop (the C++code phase taking more than 10 minutes CPU time
for this on an RS/6000 550 could be taken as a loop I think :))
class A {
protected:
static int i;
};
class B: public A {
public:
int f() { return A::i; }
};
main(){}
Satish Thatte
___________________________________________________________________
Mathematics and Computer Science Department Tel: (315) 268-6521
Clarkson University FAX: (315) 268-6670
Potsdam, NY 13699-5815 Internet: satish@sun.mcs.clarkson.edu
Author: No Author
Date: No Date Raw View
This was proposed and rejected because you can do it now:
class B {
protected:
typedef B inherited;
};
class D : public B {
void f() { inherited::f(); }
};
Neither approch (typedef not language feature) would work with
multiple inheritance.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I take this back -- although it did happen when I tried it first.
The problem is not in the xlC compiler though. Apparently, there
was some wierd interaction with the new O/S version (AIX 3.2.5) which just
got installed on the machine I was trying it on (that machine has been
periodically showing extreme load factors of 20 or so in a mysterious way
and now I have a clue about why that might be happening!).
Sorry about the confusion.
Satish
Author: No Author
Date: No Date Raw View
We are 3 students that have a post-graduate thesis. We are looking for
a presentation-tool (a library) for Windows for PC where we can
present up to 5 dimensions. The library should be used together with
for instance Borland C++ ver. 3.1 .
We shall present data from a Computational Fluid Dynamics-simulation.
The data come from simulation of heat in airstreams around oilplat-
forms.
We have already checked 3 libraries: Windows Charting Tools, GPGS
and TG-Professional.
We are interested in contact with somebody who have information about other
libraries, or demoes on these.
Piecharts, bar-graphs and similar graphs are not very good for our needs,
we must use isographs and similar graphs.
Author: No Author
Date: No Date Raw View
- Brad
-------------------------------------------------------------------------------
+ Brad Daniels | "There's only one sweeping generalization +
+ Biles and Associates | which is completely true, and this is it." +
+ These are my views, not B&A's | - Me (1994) +
-------------------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
All hell would break loose. "Clever" programmers unfettered by
any sense of restraint would make the most non-obvious code in
existence.
Given the vast number of average programmers out there, we are
in need of a language that has a sense of restraint.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
>Rod Burman
>Thanks for listening (if you have been).
S. Tucker Taft stt@inmet.com
Intermetrics, Inc.
Cambridge, MA 02138
Author: No Author
Date: No Date Raw View
-------
Q5: Where can I ftp a copy of the latest ANSI-C++ draft standard?
A: You can't. ANSI standards and/or drafts are NOT available in machine
readable form.
>>>>UPDATED 9/93
You can get a paper copy by sending a request to:
Standards Secretariat
CBEMA/X3
1250 I Street NW
Suite 200
Washington, DC 20005
Ask for the latest version of `Working Paper for Draft Proposed American
National Standard for Information Systems -- Programming Language C++'.
The last known phone number: 202-626-5738. The last known price is $25.
----------
Jamshid Afshar
jamshid@ses.com
Author: No Author
Date: No Date Raw View
The appropriate newsgroup is comp.lang.c++, not comp.std.c++.
> If I want to overload the operator==() outside a class definition,
> the compiler I'm using (Borland C++ 3.1) confuses me with an error
> message:
>
> class A {
> int a ;
> public:
> A() { a = 10 ; }
> int val() { return a ; }
> } ;
>
> int operator==( A& x, int v ) { return x.val() == v ; }
> int operator==( A* x, int v ) { return x->val() == v ; }
> Error tst.cpp 16: 'operator ==(A *,int)' must be a member function or have a par
> ameter of class type
>
> Is there a reason why I can overload operator== with a class reference,
> but not with a class pointer?
Pointers are not first-class citizens; although references aren't
either, they directly stand in for the object they refer to;
pointers do not.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
At this point, my conclusion is that the ARM is not saying exactly
what it wants to say. I don't know even know what it intends to say.
I am not a language lawyer. Am I misinterpreting anything?
Ted Law
Author: No Author
Date: No Date Raw View
In my post I gave an example of anticommuting variables ( a*b == -b*a ).
I'd like to initialize them with a double, like
anti z(3.0);
But under _no_ circumstances I want implicit type conversions double -> anti.
I have a lot of experience in FORTRAN and I found the implicit type conversion
to be very dangerous.
Well, I can oveload "=", not having a ctor anti(double), but this may not
be elegant. In addition, how will I use 'recource aquisition is initialization'
then ?
David Olsen gave the following example:
...
> Just because there exists a constructor with a single argument does
> not mean that the corresponding type conversion makes sense. I don't
> understand anti-commuting variables, so I will have to use a different
> example.
> Consider the implementation of a stack. For efficiency reasons, all
> stacks have an upper limit on their size, determined at the time of
> their construction. So the logical declaration for the stack's
> constructor might be
> FixedStack (int max_size);
> But an implicit conversion from an int to a FixedStack does not make
> much sense, and you would prefer it if there was some way to prevent
> the compiler from calling this constructor implicitly.
Wouldn't it be nice to have a contructor without implicit type conversion ?
I suggest a ctor !X (similiar to ~X, "!" stands for no implicit type conversion)
class X
{ ....
public : !X(Type y) { ... };
}
to be a constructor without allowing implicit type conversion.
This should be easy to implement and I don't beleave that this Syntax
occurs to often in existing software.
Having both types of constructors ( with or without implicit type conversion)
one can decide to use the advantages of implicit type-conversion or not.
Regards Peter Schmitteckert
-----------------------------------
Peter Schmitteckert
Lehrstuhl fuer Theoret. Physik 2
Institut fuer Physik
Uni Augsburg (Germany)
e-mail: Schmitteckert@Uni-Augsburg.de
Phone: +49-821-5977-246
Author: No Author
Date: No Date Raw View
>
> The obvious corollary [to careful exception design (dj)] is that the C++
> Standard Class Library should include a hierarchy of exception classes.
>
> (Particularly since the language is going to start throwing exceptions
> on its own.)
I've been away from comp.lang.c++ for a while. This is news to me. It
certainly seems like an "exceptionally" BAD IDEA. I'll bet it has something
to do with the add-on RTTI business. Kluges beget kluges. Am I right?
I don't want library routines that throw exceptions, and I ceratinly don't want
language features that throw exceptions. I think a routine should only
throw an exception if the calling routine has "asked for it" somehow.
I can not emphasize that enough. The writer of the calling routine presumably
knows the design of the flow of control of the program. The writer of
a library routine does not.
I like the idea of the user being able to specify an exception-handler routine,
the way operator new lets you specify a "new_handler" routine.
If the user wants it to set an error bit somewhere and return, fine.
If he wants it to throw an exception, fine. He can simply write it that
way, to throw whichever exception he wants it to. But when library
routines throw exceptions, they impose flow-of-control design
decisions unnecessarily on the programmer. If, (heaven forbid), an exception
throw is *added* to an existing library routine, it imposes design
constraints *after the fact*, quite possibly breaking perfectly good code.
Author: No Author
Date: No Date Raw View
THERE'S ABSOLUTELY NO REASON FOR THE FEATURE IS THE BIGGEST
OBJECTION!
> Let's assume for a moment the standard included a rule like:
> "When a member function is called without any (non-default)
> parameters, the (empty) paranthesis are optional"
Why only member-functions? Also the name of a function
already evaluates to its address; hence you would fundamentally
change the language. () aren't just syntactic sugar--they're
the function-call operator.
> Then, with this rule
>
> - we would not break any existing C or (older) C++ code, since
> when compiling an expression the compiler knows all about
> a member of a class (struct)
Wrong. See above.
> - we have quite fewer paranthesis since OO-programming includes
> lots of member functions without any parameters
So what?
> - it's easier to convert old C code or to change C++ code
> when a plain member of a struct/class now becomes a function,
> since we don't have to change the application programms which
> didn't use paranthesis after this member.
It's easiest to do nothing at all.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
WRONG GROUP! comp.std.c++ is for issues relating to the forthcoming
C++ STandarD...get it? Post to comp.lang.c++.
> matrix m(4,4); //a 4x4 matrix
> m[1][2] = 5;
>
> Of course I can't overload [][] (at least I haven't figured out how to do
> it.) I can overload the function call operator () like this:
There is no operator[][].
> matrix m(4,4);
> m(1,2) = 5;
>
> but this seems too unnatural. An alternative that I could live with is:
>
> matrix m(4,4);
> m[1,2] = 5;
>
> As far as I can tell from the ARM, the overloaded subscript operator [],
> and the overloaded function call operator () follow almost same rules.
> The one important exception is that () allows an expresion list with zero
> or more expressions while [] requires exactly one.
You're very observant.
> Perhaps someone in the know could explain why I shouldn't be able to
> write a member function operator[](int rows, int cols).
Because operator[] take exactly one argument--that's why. It
appears that you don't really know what is going on even with
the built-in operator []. If you have
int a[3][5];
a[1][2] = 3;
there isn't a built-in operator [][] either, but it works, right?
That's because it's: (a[1])[2].
Think about it.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Except, it seems, when operator-> is involved. My proposal
clarifies the instantiation of operator->.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
> >No. PDT must be capable of holding the difference between any two
> >elements of an array.
P. J. Plauger seems to disagree in The Standard C Library, p.
218. He doesn't cite the spec here, its thus thus his "opinion" but.
"Consider an implementation where size_t is the type unsigned int. Then
ptrdiff_t is int. You declare a data object x as an array of char whose
size is greater than INT_MAX bytes...
#include <limits.h>
#include <stddef.h>
#define N INT_MAX+10
..
char x[N];
ptrdiff_t n = &x[N] - &x[0];
.. overflow occurs ... undefined ... can't get around this ... intrinsic
weakness of Standard C ..."
It only can happen on arrays where elements are only one byte (typically
((un)?signed)? char).
Frank Sheeran
Author: No Author
Date: No Date Raw View
As far as I can tell, there is no merit to doing this at all.
size_t is for O/S-type stuff and memory. For simple loops,
stick with int as int is the natural (read: fastest) integral
type.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Most operating systems do this for you...it's called buffering!
BTW: I despise posts to such a large number of newsgroups.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I don't see what this has to do with RTTI -- the current C++
"standard" already defines this -- you can do the conversion in
friends and members of MyStack but not outside.
Perhaps you wanted to ask about the opposite conversion
(form LinkedList* to MyStack*)? In that case I would
expect the answer to be the same -- both conversions should be
available in the same contexts (where the derived object actually
supports the interface of the base object, and therefore
has a tenuous kind of IS-A relationship with the latter).
Satish
Author: No Author
Date: No Date Raw View
[ example elided ]
> Based on this example, I had concluded -- possibly erroneously -- that
>
> delete (void *) p;
>
> could be counted on to call
>
> ::operator delete(p);
>
> without attempting to call any destructor, and would therefore be valid
> in circumstances in which calling
>
> delete p;
>
> would be valid.
You might think that, and so might I. The catch is that this
example is in the commentary. Obviously, you can't "new void"
(objects of type void can not be created); if you can't create
them, how can you destroy them?
This, IMHO, if intended to be legal, must be mentioned
explicitly because, by my above statements, it is a special
case and its semantics must be defined precisely--not left for
the reader to infer.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Hello! Anybody home? A triple underscore *contains* a double
underscore!!!! The characters surrounding a double underscore
are irrelevant even if they are more underscores.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Obviously not. What if operator+ returns void? (Sick, but
possible.)
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
|> 3. Anybody know what the standard is likely to look like in this area?
|> I know that the committee has studied the problem of controlling
|> the initialization order of static objects.
Several people are working on the problem, but as far as I know, as of
yet, no one has been able to propose an acceptable solution. I keep
hoping.
--
James Kanze email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Form 2 is legal and will always be accepted; form 1, I believe
is becoming legal. IMHO, I wish they would have just picked one
and stuck with it. Yet more confusion.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
You're mixing struct-type aggregates and array-type aggregates
together and confused.
This is perfectly legal:
string s[] = { "Hello", "world" };
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I'm using a fairly recent version of Borland C++, (I forget which
one, exactly), though I hope to have the newest release within a
few days. It's being used on a 486-33 dx.
My questions:
1) Has this been done before? Do know of where I can find/ftp a
program (or even better, source code) to do this?
2) How much damage can I do to my machine by fooling with the
interrupt vectors? Will "keep" work, or is it best done in
assembly? I've never worked with this stuff before... and I'm
worried about underestimating how much memory is needed to hold
the tsr program.
3) Can it be written small enough to reside, operating, in
memory while I run my comm program (telemate)? I have 4 megs ram.
Well, that's about all. Any advice as to how to write it, where
to find existing code, good books on interrupt handling and TSR's,
etc. are muchly appreciated!
Mike
--
!----------------------------------------------------------!
Mike Marcus Do I dare
marcus@bach.udel.edu Disturb the Universe?
marcus@freezer.cns.udel.edu -T.S. Eliot
Author: No Author
Date: No Date Raw View
[ suggestion for default template types ]
Yes, people have thought of it and are still thinking of it.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Yes.
> - all/most C++ compilers would eat and understand it, i.e. is it safe
> to use it?
Most compilers *should*.
> - is the order of evaluation of constructors defined? Logic would
> dictate it not to be
Yes; see the ARM.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
--
Fergus Henderson fjh@munta.cs.mu.OZ.AU
Author: No Author
Date: No Date Raw View
It doesn't exist yet.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Your example shows you casting a pointer to base to a pointer
to derived--the exact opposite. *That* is forbidden in the
ARM.
> For example, the following does not compile. Is this a
> problem of this specific compiler?
No.
> class base {};
>
> class deriveL1A : virtual public base {};
> class deriveL1B : virtual public base {};
> class deriveL2 : public deriveL1A, public deriveL1B {};
>
>
> int main() {
> deriveL1A d;
> base* b = &d;
>
> deriveL1A* c = (deriveL1A*) b;
> }
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
[ code elided ]
> Is something along these lines legal? Is so, could someone tell me
> what the syntax looks like?
>
> template< class V, class T<V> >
> V computeXmin( const T<V>* arr, int n )
> {
[ code elided ]
> }
template< class V, class U >
Just *assume* that U is a T<V>; if it isn't the user will get
errors during compilation. (This is what documentaion is for.)
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
I think the original poster did a good job: the non-public
inheritance lattice of a given class is of no concern to the
user; yet objects still must be constructed and destructed
(destroyed for English purists) regardless. Since it seemed
obvious to be that the original posted had a grasp of this
concept, it seemed unnecessary to elaborate. It seemed to me
that he was just asking "why won't the compiler allow this?"
to which I succinctly responded.
That seemed simple enough.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
My 0.02Pf
Achim Gratz
--
ASSI Softworks
-+==##{([****************************************])}##==+-
E-Mail to: gratz@iee.et.tu-dresden.de
with CC to: gratz@ite101.inf.tu-dresden.de
Phone: +49 351 463-3009
Author: No Author
Date: No Date Raw View
1. It's legal.
2. It's redundant. (Why do it?)
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Wrong newsgroup! std means things having to do with the forth-
coming standard; use comp.lang.c++.
> When declaring variables, which method is the most correct?
>
> i.
> for (int j=0;j<1000;j++)
> for (int i=0;i<1000;i++) {
> int k = i*j;
> cout << k << endl;
> }
>
> ii.
> int j,i,k;
> for (j=0;j<1000;j++)
> for (i=0;i<1000;i++) {
> k = i*j;
> cout << k << endl;
> }
>
> Please can you give me any points for either method, for or against.
1. Something is either correct or it isn't.
2. Both are syntactically correct.
3. They are *not* semantically equivalent as 'k' is local to
the inner scope.
4. The former is preferred (obviously; that's why the for statement
was enhanced in C++).
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
class programmer :public employee{
...
};
employee *pe = new programmer;
so with this extension, you can know do things like:
typeid(pe) == typeid(employee*)
but is there a way to do:
employee *fred;
fred = new typeid(*pe);
[obviously this is not a reasonable syntax, but what I want is fred to
a new programmer.]
Is something like this available?
Also, being new to this standards business, is there a place to obtain
the description of accepted extensions?
Thanks.
Mark.
=-=-=-=
... the end of all our exploring will be to arrive where we
started and know the place for the first time." -- T.S. Eliot.
Author: No Author
Date: No Date Raw View
1. wrong newsgroup.
2. coding conventions are useless.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Wrong newsgroup!! std has to do with the standard...get it?
What do you think comp.lang.c++ is for?
> Let's have the following class
>
> class foo {
> static int x;
> static int y;
> int z;
> public:
> static void f() const; // compiler complains
> ....
> };
>
> My question is :
>
> In foo::f(), I don't change neither foo::x nor foo::y, so why
> can't I declare foo::f() "const" ?
Because x and y aren't members of any particular object and
f() never operates on any pariticular object unless passed
as an argument which, in this case, it isn't.
> Conceptually, I should be able to put the const keyword
> there.
Const with respect to what? Again, there is no object.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
>In article <744662863@amazon.cs.duke.edu> dsb@duke.cs.duke.edu (Scott Bigham) writes:
>>In article <rfgCBAw1F.7Hx@netcom.com>, Ronald F. Guilmette
>>(rfg@netcom.com) suggests the following syntax extension to implement
>>compile-time-enforceable template constraints:
>
>HOLD ON A SECOND! I just want to clarify that it was *YOU* and *YOU ALONE*
>who decided to use the term "template constraints" [...]
Er um, check the title of the thread. It was that way when I got here.
And you did say, did you not, that given:
>>> template <class T { class M; }> void template_function (T arg)
that it would be a _compile-time_error_ to attempt to instantiate
template_function() with a class that did not contain a type name M?
Sounds like a template constraint to me.
>Indeed, I am somewhat disheartened that the follow-ups on my simple idea
>for solving this one small (syntax) problem have blossomed out into
>discussions of vastly more complicated "template constraint" schemes [...]
It surprises me that this surprises you. The syntax you suggest:
>>> template <class T { class M; }> void template_function (T arg)
^^^^^^^^^^^^
looks very much like a partial class definition for T; it should come
as no surprise, then, that people would try to put other elements of a
class definition into it.
Besides, the most straightforward method of fixing the syntax problem
would seem to be to disallow the extra parentheses in the declarator,
since that's what's really causing the ambiguity in the first place:
>>> int a;
>>>
>>> template <class T> void template_function (T arg)
>>> {
>>> T::M (a); // function call
>>> T::N a; // declaration
>>> }
>(For some additional information relating to YOUR ambitious template
>constraint scheme [...]
Not mine alone, considering the number of people who independently
suggested it.
-sbigham
--
Scott Bigham | The opinions expressed above are
dsb@cs.duke.edu | (c) 1993 Hacker Ltd. and cannot be
| copied or distributed without a
| Darn Good Reason(tm).
Author: No Author
Date: No Date Raw View
See: C++ Report, 4(4), May 1992.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
In other words, if you want the above ability, then use pointers; they
do everything refs can do, and more; and a lot more damage, too.
============================================================================
Jim Heliotis Voice Phone: 716-383-7410
Xerox Corporation FAX Phone: 716-383-7395
435 W. Commercial St. Mail Stop: 803-01A
East Rochester, NY 14445 Electronic Mail: JEH.ROCH803@Xerox.COM
============================================================================
Author: No Author
Date: No Date Raw View
You don't just need a coding standard, you need a netnews posting format
standard ;-)
--
Kent Williams -- williams@cs.uiowa.edu Work(626-6700) Home(338-6053)
"Science has come with wonderful ways to cure sick people one at a time,
and to kill healthy people thousands at a time" -- guy on NPR
Author: No Author
Date: No Date Raw View
I missed something: Why do you need to flavors of Proxy? I
typically have:
class FooProxy {
// ...
public:
FooProxy& operator=( ... );
// ...
};
class Foo {
// ...
public:
FooProxy& operator[]( int );
FooProxy const& operator[]( int ) const;
// ...
};
What problem is being solved with two Proxies?
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
It is:
ftp ftp.su.edu.au
cd ANSI
get 93-0055.ps
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Er, that's:
cd /pub/C++/ANSI
or at least that's closer to the truth.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
|> We haven't implemented 'namespaces' yet, but supposing that it is accepted
|> into the draft, we'll get started. Why? Because our user community has also
|> expressed a need for a solution in this area. That is, of course, the only
|> reason for doing any of this stuff.
|> To reiterate, I think that the extensions that have gone in since the
|> standardization process has started have been improvements. I also think
|> that encouraging implementors to implement the extensions results in
|> complete extensions. Lastly I don't believe that these extensions would
|> be implemented if they weren't in the Working Paper. Certainly not
|> as widely. Its fine to wish for implementations. The only way to get
|> them to happen is vote 'em in. In a world of conformance to standards,
|> it is hard to convince companies to invest in proprietary solutions.
I don't think the problem has been with the quality of the individual
extensions (although I personally have some doubts concerning
namespaces). The problem is the trade-off, extensions *or* a standard
anytime soon. My guess is that each of the aforementioned extensions
have delayed or will delay the standard by about a year. (Maybe a bit
less for exceptions, certainly more for templates.)
My customers are beginning to shy away from C++, because they ask
themselves: "if the experts on the C++ committee don't understand the
language well enough to be able to define it, how can we expect our
programmers to be able to write portable programs in it?" Now I know
enough about C++ *and* the current standards effort to know 1) you can
write relatively portable programs with the language just as it
stands, standard or no, and 2) most of the extensions *are* an
improvement, and address important issues. But there is a perception
problem here. One of the more frequent criticisms of C++ is that it
is overly complex. By continually delaying the standard, we add to
the effectiveness of this arguement.
--
James Kanze email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
Because the term 'package' is vague; namespace is precise. "Our
code is packaged" could tell me that they put it in a pretty box.
I would have actually preferred "scope"; but I suspect that such
a name would break old code.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
And even if we get operator.(), it will be a unary operator (like
operator->()), and so couldn't be used for concatenation.
And I find that '&' and '|' have the wrong precedence. And of course,
they are also commutative in C++.
So it looks like we're left with '/'. Let's see, precedence is OK,
not commutative. How does it look?
String big = string1 / string2 ;
Looks OK by me.
Seriously, all logic aside, most users seem to expect '+', so that's
what I use in my String class.
--
James Kanze email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
I'll never tell.
Author: No Author
Date: No Date Raw View
"The initialization of nonlocal static objects in a translation unit
is done before the first use of any function or object defined in that
translation unit."
If I have two source files, each defining a class and declaring a
global instance of that class, and I want to guarantee that file A's
object is constructed _first_, it seems like I can call a function in
file A from the constructor of B that refers to the instance of object
A. I think code would be easier to read:
=========[A.C]===========+=========[common.H]=======+===========[B.C]========
#include "common.H" | #include <stdio.h> | #include "common.H"
| struct |
A::A() | { | B::B()
{ | int x; | {
printf("A::A()\n"); | A(); | printf("B::B()\n");
} | }; | a();
| | }
A ay
| { | B bee;
void a() | int y; |
{ | B(); |
ay.x = 9; | }; |
printf("a()\n"); | |
} | extern void a(); |
| extern void b(); |
int main() | |
{ | |
return 0; | |
} | |
=============================================================================
I want object ay to be constructed before object bee. If bee is
constructed first, it calls a(), which is a use of a function in
foo.C, and it uses object ay. The quoted sentence of the ARM seems to
say that the initialization of ay is done before a() is called, so
this provides a mean of forcing the order of construction of global
objects.
Is this what the ARM is really saying, or am I misinterpreting this
sentence?
Amit
P.S. I know that there isn't supposed to be a way to force
the order of construction of global objects, but it
looks like the ARM lets me do it...
--
--
Amit J Patel, patel@shell.com
Author: No Author
Date: No Date Raw View
... to you. To me it just looks plain wrong.
(Back when dinosaurs roamed the earth, I received a master's degree in math.
Had to study algebra and all that.)
There was a time when, in C Classic at least, the compiler was free to
regroup "+" expressions, taking advantage of the commutivity of operator+.
I assume that in C++ that is off, and + is now stricty left-associative, but
I don't think it is very elegant to take advantage of the new rule.
Instead abusing operator + so that you can say,
StringA = String1 + String2 + String3;
how about abusing the << operator instead, in a way that has already become
established as a C++ idiom?
StringA << String1 << String2 << String3;
It is easily done:
String& String::operator<< (const String &str) {
this->append(str);
return *this;
}
Author: No Author
Date: No Date Raw View
> One possiblility would be to use operator| or operator||.
Bingo. Operator "|" is perfect.
Author: No Author
Date: No Date Raw View
First, this is the **WRONG** newsgroup for such questions;
post to comp.lang.c++!!!
Answer: Neither. I can't believe Borland's compiler is that
out of date (you do have a recent one?). It supports an older
version of the language.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
> There may be good reasons having to do with precedence or
> whatever for using the * operator, but at the "intuitive"
> level it just doesn't work.
For those of us who have studied math, using + for concatenation is not
intuitive; It is, well, *irksome*. Addition is commutative. As I have
explained in previous posts, operator+ is invariably reserved for
commutative functions, but concat(A,B) is not the same as concat(B,A).
Too bad there is no "adjacency operator" except for literal strings.
AWK has such a feature. To form the concatenation, STR, of two strings
STR1 and STR2 you write,
STR = STR1 STR2;
But since there is no adjacency operator, what should be used?
Operator+ goes against its math roots, and apparently some people
would be puzzled by operator*. Probably the best answer then is not
to use either operator+ or operator*. I propose the following:
friend String concat(String left, String right);
... and perhaps also
void String::append(String suffix);
void String::prepend(String prefix);
... or some combination of variations thereof, with const reference declarators
sprinkled in where deemed expedient.
Author: No Author
Date: No Date Raw View
ARM, pp. 7-8. There will most likely be a String class;
perhaps others; it's too soon to tell.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: No Date Raw View
---first page of the comp.lang.c++ FAQ; contains info for getting all of it---
==============================================================================
Document: Frequently-Asked-Questions for comp.lang.c++
Revision: 9-Feb-92
NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE AUTHOR
PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR
IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH
RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY
PARTICULAR PURPOSE.
Availability: This is available via anonymous ftp
from: sun.soe.clarkson.edu [128.153.12.3]
in the file: ~ftp/pub/C++/FAQ
Without FTP: You can also get it by sending electronic mail:
| To: archive-server@sun.soe.clarkson.edu
| Subject: send C++/FAQ
This will help those who don't have ftp.
See also: comp.lang.c's FAQ appears at the beginning of every
month in that newsgroup, and is maintained by
Steve Summit (scs@adm.mit.edu).
Author contact: Marshall Cline
Paradigm Shift, Inc
65 N. Main St. / Norwood NY 13668-1121
voice:315/353-4585, fax:315/353-6110
email:cline@sun.soe.clarkson.edu
Copyright: Copyright (C), 1991,1992 Marshall P. Cline, Ph.D.
Permission to copy all or part of this work is granted,
provided that the copies are not made or distributed
for resale (except nominal copying fee may be charged),
and provided that the `NO WARRANTY', author-contact,and
copyrightnotice are retained verbatim and are displayed
conspicuously. If anyone needs other permissions that
aren't covered by the above, please contact the author.
==============================================================================
Author: No Author
Date: No Date Raw View
CASE 1: I am defining a class that adds some extra functionality
to ordinary C character strings (i.e. char * with an assumption
about terminating null characters). My additional functionality
doesn't matter. What does matter is that I want these things
(call them Terms) to be treated as ordinary char * objects when
passed to any of the string-handling functions in <string.h>,
and I want operator [] and operator + to work on them.
First try:
class Term
{ private:
char * P ;
// ...
public:
/*conversion*/ operator char * () { return P ; }
char & operator [] (unsigned short X) { return P[X]; }
char * operator + (unsigned short X) { return P+X ; }
// ...
};
Given the declarations "Term T; unsigned short US; int I", I get no
problem from T[US]. That's an exact match to Term::operator[](unsigned
short). But if I try T[I] with IBM's xlC compiler, it complains about
an ambiguity. Apparently, the compiler finds that the best match for
the "first" argument is {::operator[](int)} and the best match for the
second argument is {Term::operator[](unsigned short)}, and the inter-
section of the two sets is empty. That's a legitimate ambiguity,
and I can eliminate it by not defining Term::operator[] or Term::
operator+, and laying the whole burden on the conversion operator.
Second try:
class Term
{ private:
char * P ;
// ...
public:
/*conversion*/ operator char * () { return P ; }
// ...
};
Now the xlC compiler is satisfied, but the Borland C++ compiler
kicks up a fuss, complaining that it has no way to apply operator []
to a Term. This is apparently an attempt to apply Rule R in a very
strict manner: _Because_ the first argument of operator [] is a
class object, Term, don't consider any user-defined conversions
even when trying to find the "best match" for other arguments.
The xlC compiler is more relaxed in its interpretation. It doesn't
consider ::operator [] when matching the first argument (It wouldn't
be the best match anyway), but it does consider it when matching the
second argument. After all, both ::operator[] and Term::operator[]
are in scope. Who is right? My guess is Borland, but there's a
nagging question about the rationale underlying the rule that I will
come back to in case 2.
I cannot find a good workaround that is acceptable to both compilers
and preserves my intended semantics, that a Term appear to the
client of the class to behave like a character string. Here is
what I've considered:
1. Replace the conversion with an explicit member function:
Permits operator[] to be used naturally, but forces such
unsightly things as "strlen(T.Body())".
2. Require the client to disambiguate operator []. Thus,
"strlen(T)" works, but to use "T[0]" the client has to
enter either "T[(unsigned short) 0]" or "T::operator[](0)".
3. Cover all the bases. Define a whole bunch of T::operator[]
functions, taking arguments of type char, unsigned char,
signed char, short, unsigned short, int, unsigned int,
long, unsigned long. Hope I can get away without doing
the same for float and double. This is the best solution
yet. The client won't run into trouble until he/she tries
defining a class with a user-defined conversion to an
integer type, and applying T::operator[] to an object of
_that_ class.
Have I missed anything?
CASE 2: I desire, for reasons I think are good ones, to define
a MessageHandler class that behaves like an ostream, but allows
you to bracket a set of output operations as constituting a
"message" which gets some sort of special handling (via virtual
functions so derived classes can be defined for different types
of special handling). The intended usage is something like:
// Declaration
MessageHandler Msg (cerr) ; // Argument is the ostream that
// will (by default) receive
// the processed message.
// Usage
Msg << Text << Variables << Whatever << AndSoOn << Msg.End ;
The intention was that the MessageHandler object would be convertible
to an ostream& for application of operator <<. The Msg.End object
has a special private type with its own operator << (ostream&, ...)
definition that triggers the desired end-of-message processing.
Naturally, this won't work. The conversion MessageHandler::operator
ostream& is _excluded_ from consideration by rule R when we are
trying to match arguments for operator <<. OK. That's the rule.
Who am I to argue? Let's try to find a workaround.
1. Everything would be fine if we made MessageHandler a derived
class based on ostream, right? Then it would inherit operator
<< and all the other ostream operators in a nice, convenient
way ... Not quite. It wouldn't inherit anything defined
as a friend (i.e. friend ostream& operator << (ostream&, ...) ).
Of course, friends aren't covered under Rule R, so that
the automatic conversion from MessageHandler to ostream
(derived-to-base) would be usable in that case.
It also means that the base ostream must be included in
the class (as opposed to including a reference to it).
This means that the base ostream must actually have type
ostream_withassign, so it can be initialized from an existing
stream. (an aside: The documentation I have for iostreams
does not tell me if the assignment operator is typed as
"ostream_withassign::operator = (ostream &)" or as
"ostream_withassign::operator = (ostream_withassign &)".
In the second case, my MessageHandler class would have to
require that any ostream used to initialize a MessageHandler
or any ostream supplied to a hypothetical redirection
qualifier (Msg.To(cout), for example) would have to be
an ostream_withassign. cout and cerr are so defined,
but do we really want the clients to have to know about
this if they are using their own streams?
The drawback is that the "base" ostream is not necessarily
the one that receives the data inserted by the << operator.
One of the things a MessageHandler can (and will WANT to) do
is set up a temporary ostrstream to gobble up the text of the
message and hold it for further processing at Msg.End time,
after which processing it is sent to the base stream. To
make this work, we have two options.
We could let the base element be the ostrstream we use for
the temporary message-capture operation. Then the "target"
stream that we eventually write to (and use as an initializer)
can be implemented as an ostream& member. That solves the
initialization worry mentioned above. But we are left with
this base ostrstream to deal with. One problem: not all
classes derived from MessageHandler need the overhead of
buffering the message in an ostrstream; this strategy would
force them to do it anyway. Another worry: my iostream
documentation doesn't tell me if an ostrstream can be
reinitialized and reused after the output is extracted by
the ostrstream::str() function.
The second option is to copy the "target" ostream into
a reference member, as well as assigning it to the base
ostream. Then a MessageHandler that doesn't need to
capture the message in a string can just rely on the
normal inheritance of operator <<, while one that uses
a temporary ostrstream has to assign it to the base
stream at the start of each message. This means that
the base stream must have type ostrstream_withassign,
and when we initialize it from the target stream we have
to explicitly cast-to-derived (from ostream to ostrstream_
withassign). Awkward, but not fatal. What worries me is
that ostream_withassign would not have been singled out
as a separate class if ostream assignment were a cheap
operation (I can imagine things like duplicating the buffer,
and so forth). I am wary of incurring this kind of overhead
once or twice for each message.
2. A completely different strategy is to replace the conversion
from MessageHandler to ostream& with an explicit function.
I chose to use operator (), the overloaded function call,
declared as
ostream & MessageHandler :: operator () ()
This changes the usage semantics slightly:
Msg() << BODY << OF << MESSAGE << Msg.End ;
Not a big deal. We're used to typing extra ()'s. But now
consider adding qualifiers to a MessageHandler. For instance,
a redirection qualifier MessageHandler::To(ostream&) to
override the default target stream for this message, or a
page-width qualifier MessageHandler::PageWidth(int) that
supplies a width at which the message is supposed to be
wrapped onto the next line. What result type should these
qualifiers have? If they return a MessageHandler&, the
client has to tack on an extra pair of parentheses in a
less understandable way than we just did above:
Msg.To(cout)() << ...
If they return an ostream&, then you can't compound
qualifiers (i.e. Msg.To(cout).PageWidth(65) is illegal).
3. Finally, we could define MessageHandler::operator << for
every type for which ostream::operator << is defined (and
ditto for other ostream member functions). This works, but
requires that I, as the implementor of MessageHandler, know
(or infer) a lot of implementation-specific information about
the ostream class. Besides, it makes the class definition
rather ungainly to manage.
To summarize: CASE 2 has given an example of what I think is a
useful feature that is currently very awkward to implement and use,
but would be very easy to implement and use if Rule R were
relaxed to the point of allowing user-defined conversions. CASE 1
shows that two compiler implementations have chosen different
interpretations of Rule R, creating an incompatibility that can be
eliminated either by tightening the definition of rule R to favor
one interpretation or by relaxing it so that it doesn't interfere.
My request to the community is that we either justify rule R and
tighten up its interpretation or consider eliminating it to get
the added functionality of CASE 2.
For those of you who stayed with me so far, I apologize for being
so long-winded. I could not find a brief statement of the problem
that would accurately convey what I wanted to say.
+------------------------------+ -- Jens M. Dill
| Nothing is a waste of time | Notis Systems, Inc.
| if you can learn from it. | dill@twain.notis.com
+------------------------------+ 415 390 9505
Author: No Author
Date: No Date Raw View
There are a few kludgy tricks you can try.
You can define a class to explicitly allow class X to break the security
of Y. For instance:
class ExplicitelyBypassYsSecurityForClassXOnly{
protected:
struct MyFriend { MyFriend() {} };
};
// Declare intentions to peek at Y's privates.
template<class T> class X : protected ExplicitelyBypassYsSecurityForClassXOnly{
...
};
// Declare decision to expose some of privates to any one that
// explicitly declares it's intensions to peek.
class Y : private ExplicitelyBypassYsSecurityForClassXOnly{
private:
Type1 var1;
Type2 var2;
public:
Type1& peek_var1(MyFriend&) { return var1; }
const Type2& peek_var2(MyFriend&) { return var2; } // look but don't touch
...
};
In order to access Y's privates X may use call either peek_var1() or
peek_var2() as peek_var1(MyFriend()). There are a few caveats to this approach,
the biggest of which is that any class that derives from
ExplicitelyBypassYsSecurityForClassXOnly can break Y's security. Because of
this I chose a very long and descriptive name -- the programmer has been
explicitly been warned that only X should be derived from this class.
The second problem is that total access to Y is not given, only access to
individual members. This can be fixed by separating the shared parts of y
from the rest of y:
struct Y_implementation{
// ...
};
class Y : private ExplicitelyBypassYsSecurityForClassXOnly{
private:
Y_implementation y;
public:
Y_implementation& peek_private(MyFriend&) { return y; }
...
};
I know, it's not elegant as it should be and requires some programmer
discipline, but it works.
Take care
Robert
--
/----------------------------------+------------------------------------------\
| Robert N. Deviasse |"If we have to re-invent the wheel, |
| EMAIL: g2devi@cdf.utoronto.ca | can we at least make it round this time"|
+----------------------------------+------------------------------------------/
Author: No Author
Date: No Date Raw View
This presupposes that you previously declared at global scope
template<class T> class X;
either as a forward declaration (above) or the entire class.
The friend declaration is a reference to the global one. The
spirit of what the ARM *means* is that a "new" template, i.e.,
previously unseen, declaration is illegal in class scope.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
cfront isn't wrong because there's nothing for it to be wrong
with respect to. As I just said in another post, if you've of
the sort that has got to see it in black-and-white in the ARM,
then "no" there is no official way to do it.
This ommision in the ARM is addressed in an ANSI working paper
by Spicer (sp?) and I can't see any reason why it won't become
"official" since it's something that *should* be in the
language.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
======================================================================
Pawel Gburzynski, Associate Professor, Department of Computing Science
University of Alberta, Edmonton, Alberta CANADA T6G 2H1
e-mail: pawel@cs.ualberta.ca, tel: (403) 492-2347, fax: (403) 492-1071
======================================================================
Member of the League for Programming Freedom --
write to league@prep.ai.mit.edu
======================================================================
Author: No Author
Date: No Date Raw View
eg.
struct X
{
operator int ();
int operator + (int);
};
void f (X a, X b)
{
a + b; // a.operator+(b.operator int());
// rather than
// a.operator int() + b.operator int();
}
Is the above always the case. Are class-operators always preferred over
class-conversions or is overload resolution deciding which to use.
ie:
built-in: operator+ (int, int) would require user-defined conversions
of both operands to int.
whereas: X::operator+(X&, int) only requires user defined conversion
for the 2nd argument.
---
Next question. On the two DOS compilers I've got here (Zortech & Borland),
the following code produces different results:
struct X
{
operator int ();
operator int*();
};
void f (X& x)
{
+x; // both compilers accept this; surely it's ambiguous. the
// operand can be arithmetic or pointer-type. 'x' can be
// converted to a pointer or arithmetic type.
!x; // borland faults this. ambiguity between operator int and
// operator int* (surely this should happen for unary-).
// zortech allows this :-) no ambiguity.
}
confused...?
--
Simon Huntington
Software Interrupt Developments. Leeds, UK.
Author: No Author
Date: No Date Raw View
Okay, fine...that's good enough for me.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
This code is completely illegal. You're deriving from a class
that hasn't been seen yet (base).
operator-> is supposed to have a (non-int) return type and is not
supposed to take an argument.
Furthermore, you apply it to an *object* and *not* a pointer.
Consult a C++ book.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Yes.
> Its not clear to me from reading the ANSI C++ WP Jan 28 1993, sections
> 9.6 and 3.6.1, or the ARM.
It seems plain as day on p. 185:
...C++ allows a bit-field to be of any integral
type...including their signed and unsigned varieties.
> Six out of eight different C++ compilers seem happy about it.
Then 2 out of 8 are broken.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
"Polymorphism" dates from 1839, so says my dictionary, but to
computing, it is a pretty new word -- maybe fifteen or twenty years?
The CS meaning is not in my dictionary. Anyway what I am getting around
to is, in my lexicon, templates perform a kind of polymorphism, namely
overloading. Function templates overload function names directly.
Class templates overload the member functions and access operators
to the class members.
What is your definition of "polymorphism"? For that matter, what do
you mean by "object oriented programming"? Can't you _orient_ your
program around _objects_ without using dispatch tables (veetables)?
Author: No Author
Date: No Date Raw View
> This is top of the extensions working group's priority list. The proposal
> on the table looks like this:
>
> namespace X {
> class String { ... }; // library X's string
> // ...
> }
>
> namespace Y {
> class String { ... }; // library y's string
> // ...
> }
>
> void g()
> {
> using Y::String; // String refers to Y::String
> // in this scope
>
> String s = "asdf"; // using Y's string
> // ...
> }
I think that...
void g() {
using Y::String {
String s = "asdf"; // using Y's string
// ...
}
}
...is perhaps an improvement (?) because it reinforces the scope
of String. This would also allow you to do things like this:
void h() {
using Y::String {
String s = "asdf"; // using Y's string
// ...
}
using X::String {
String s = "ghjk"; // using X's string
// ...
}
}
...unless, of course, the rule for the former syntax meant that
"String means Y::String until told otherwise" so that one could
redo the last example like this...
void h2() {
using Y::String;
String s = "asdf"; // using Y's string
// ...
using X::String; // change what String means
String s = "ghjk"; // using X's string
// ...
}
Comments?
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Well, ok; IMHO, it's ugly, but I'll live.
>> redo the last example like this...
>>
>> void h2() {
>> using Y::String;
>>
>> String s = "asdf"; // using Y's string
>> // ...
>>
>> using X::String; // change what String means
>>
>> String s = "ghjk"; // using X's string
>> // ...
>> }
>>
> Nope, cant do that. The using is more or less
> equivalent to
>
> typedef Y::String String;
Is there any reason why the above typedef can't be used instead
of introducing the "using" keyword? This makes more sense and
seems more orthogonal to me.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Then you are defining a "memory provider", like an array. I have no
quarrel with that. It is not a single variable, but instead makes
visible to the client many internal variables, each of which can store a value.
I just want it made clear whether the class provides memory for the client
to use, or whether it effectively stores a composite value, in which case
the internal memory should be none of the client's business.
I would prefer not to have container classes that let the internal memory
pointers leak out and then invalidate them, even if they are documented not
to be valid after the next time the container is accessed. I think that
is asking for trouble.
Author: No Author
Date: No Date Raw View
>> ... I want the draft standard for the String class (so I can write a
>> conforming shell around an existing String class). Could someone please
>> post it?
>
> That wasnt quite what I meant. What I meant was what do you want
> in a string class? Anyone out there: what do *you* want?
Oh. Well, I'm not completely sure, but I could get by initially with just the
basics: lists, queues, maps, graphs, et cetera. And oh yeah, regular
expressions.
I think I want the following properties. (I'm sure someone will tell
me where I am wrong.)
0. Skinnny interfaces. Classes should be unintrusive. They
should not require that the objects they manipulate be derived from a
single do-everything base class. Which brings us to...
1. Use virtual functions only when the actual type of an object can not
be known until runtime. When the type can be known at compile time, use
templates, not virtual functions.
2. Keep implementation details out of the "signature" of classes.
GOOD
template<class Key, class Value>
Map {
const int default_size = 32;
public: Map(int initial_size = default_size);
//...
};
NOT SO GOOD
template<class Key, class Value, int Size>
Map {
public: Map();
//...
};
3. For operator[], indexes always start at zero.
4. Containers should store and return values, not references.
(If the user wants to store and return values that happen to be pointers,
fine. Then the user is responsible for creating and deleting the objects
pointed to.)
5. Be able to turn off assertion checking in time-critical sections. A botched
assertion should call "abort" rather than throwing an exception.
Author: No Author
Date: No Date Raw View
I agree with Fergus.
How often do you need to keep a collection of stacks, some of which
are implemented one way, some in another? It is only when the implementation
type of the stack can not be known until runtime that virtual functions
are needed. I can't remember ever needing that functionality. Templates
decide the question at compile time.
-- Dave
Author: No Author
Date: No Date Raw View
> ... And make sure each of them has an associated iterator class.
> [I prefer iterators based on the 'pointer' model - dereference to access
> the value, increment operator to go th the 'next' item].
There are some classes that are meant to more or less mimic "raw" memory.
A self-extending array is an example. For such as that, the incrementing
pointer is okay. The bargain with the array class is, you give me access
to memory which I will use as I please.
But I would prefer that most container classes be designed to store and
return values, not to offer memory that is externally accessible. In that
case, you don't want the application to be able to modify the internals
of the object directly...
HashTable map;
addSomeAssociations(map);
HashIter iter(map);
for(;iter;iter++) {
*iter = newValue(); // Generally bad idea, I think.
}
... but the canonical return value from operator* is a reference. I don't
think container classes should return references to their internal objects,
and I think that operator* should work as expected. Therefore, I think I
prefer a "next" function that returns a value.
Author: No Author
Date: No Date Raw View
Can you be more specific? Do you mean "list" and in singly/doubly linked list?
What is list surgery?
Author: No Author
Date: No Date Raw View
Yes; return a T&.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
Thomas.
Author: No Author
Date: No Date Raw View
I want the draft standard for the String class (so I can write a conforming
shell around an existing String class). Could someone please post it?
Of course, I would also like to have a standard set of container classes,
but apparently they are not considering that problem.
Author: No Author
Date: No Date Raw View
Or you redesign things such that you don't have functions with
a lot of default arguments; yes, this is harder, but, IMHO, often
leads to a better, simpler, more elegant design.
Default arguments are nice, but, like anything else, should not
be overused (or abused!).
>> Also, it's just not worth the extra baggage of making C++ even
>> bigger and complicating things for the (negligable) benefit.
>
> Maybe. But they would be of more than negligable benefit.
In *your* humble opinion.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
There's basically two approaches you code take to reading/writing such
an address. 1) You can convert it to/from an integral type, and write/read
that -- except that such an integral and back conversion is not guaranteed
to exist, but rather is implementation dependent. 2) You can convert
it to a void* and use the %p formatter to write/read it back within
the same program execution. In which case the results are guaranteed to
be implementation dependent *except* for the fact that the original void* and
the read-back void* are gauranteed to compare equal.
This second case raises a couple of issues: Is a void* sufficient to keep
a Foo object alive? And can a pointer be written to store, and then later
resurrected and expect to keep an object alive? To me the answer to both
cases is obviously "no". Note that using a form of swizzling and lookup
table it is possible to make the written and read void* match in spite of
moved objects between the write and read. The trick is that instead of
writing and reading an address, a unique obid is logged and written instead.
The GC system tracks the correspondence between that obid and the
"changing" address of the actual object as it is moved. When the %p is
read back in, the written out obid is used to refer to the correspondence
in order to find the current object address, and that value is put in
the void* read. So, the guarantee that the written and read void*'s
compare equal is met. There is no guarantee that the object is kept
alive though -- unless a live pointer is maintained. Or unless a mere
write of such a pointer is used to signal keeping that object alive
indefinitely.
Author: No Author
Date: No Date Raw View
Which is worse: remembering the argument order or remembering
the keywords? The keywords should be optional; if they are,
then in places where they're not used to call a function, you're
back to remembering the argument order.
Upshot: keyword arguments, in practice, are no help.
Also, it's just not worth the extra baggage of making C++ even
bigger and complicating things for the (negligable) benefit.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
[ ... ]
First, garbage-collection doesn't necessarily do compaction; it
could just add the free-stuff to a free-list and leave
everything else where it is.
Second, if GC were implemented for a set of objects, then you,
the user, would (should!) not be permitted to have a *real*
pointer to any object; rather, you'd have a handle or
something.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
"For explicit uses of operator new(), it may also be the job of the
constructor to call an operator new() function to allocate memory."
Futhermore, Section 12.5 (p. 282) gives an example where operator new() is
overloaded and states:
"Here, an implementation is allows to place a call of operator new() in the
body of the constructor to implement the constructor semantics (see 12.1)."
Since the actually memory allocation *could* occur inside the constructor,
there is no guarentee that 'f' is points to the allocated memory in the
event where the constructor throws an exception. Also, I could not find
any statement in ARM that requires this memory to be freed.
Stating this, I believe there is a safe way to handle this problem.
Consider:
Foo* f = (Foo*)0;
void* t = (void*)0;
try {
t = Foo::new(sizeof(Foo)); // Legal, operator new is static (ARM 12.5);
f = new (t) Foo(...); // Placement new.
}
catch(...){
if ( (f == (Foo*)0) && (t != (void*)0) )
delete t;
}
In the above example, if allocation fails there isn't any problem. If the
constructor fails, 'f' isn't assigned, but 't' points to the allocated
memory and can be safely deleted.
-------------------------------------------------------------------------
Heeren Pathak | Millions long for immortality who do
pathak@mitre.org | not know what to do with themselves
Mitre Corporation | on a rainy Sunday afternoon.
(617) 271-7465 | -- Susan Ertz
-------------------------------------------------------------------------
Disclaimer: Mine not Mitre's.
Author: No Author
Date: No Date Raw View
...
Yet another misposted question. This one was about calling a
ctor directly from within a *friend* op=.
You should post "How do I..." questions to comp.lang.c++; the std
is for *standard*...get it? About the language standard?
Anyway, op=() *must* be a member and it has no business constructing
a new object...you're s'posed to be replacing the current object's
contents.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: No Author
Date: No Date Raw View
"For explicit uses of operator new(), it may also be the job of the
constructor to call an operator new() function to allocate memory."
Futhermore, Section 12.5 (p. 282) gives an example where operator new() is
overloaded and states:
"Here, an implementation is allows to place a call of operator new() in the
body of the constructor to implement the constructor semantics (see 12.1)."
Since the actually memory allocation *could* occur inside the constructor,
there is no guarentee that 'f' is points to the allocated memory in the
event where the constructor throws an exception. Also, I could not find
any statement in ARM that requires this memory to be freed.
Stating this, I believe there is a safe way to handle this problem.
Consider:
Foo* f = (Foo*)0;
void* t = (void*)0;
try {
t = Foo::new(sizeof(Foo)); // Legal, operator new is static (ARM 12.5);
f = new (t) Foo(...); // Placement new.
}
catch(...){
if ( (f == (Foo*)0) && (t != (void*)0) )
delete t;
}
In the above example, if allocation fails there isn't any problem. If the
constructor fails, 'f' isn't assigned, but 't' points to the allocated
memory and can be safely deleted.
-------------------------------------------------------------------------
Heeren Pathak | Millions long for immortality who do
pathak@mitre.org | not know what to do with themselves
Mitre Corporation | on a rainy Sunday afternoon.
(617) 271-7465 | -- Susan Ertz
-------------------------------------------------------------------------
Disclaimer: Mine not Mitre's.
Author: No Author
Date: No Date Raw View
A `type-specifier-list' is only allowed to be a relatively simple type
declaration (eg, a typedef name, "class Foo", "Foo::Bar", "int",
"const enum Colors", etc).
A `ptr-operator' is allowed to be "*", "&", "* const", etc. It is
also allowed to be a data member pointer like "Foo::*" or
"Foo::Bar::* const".
Therefore, the following are syntacticly legal:
struct S {
int i;
operator char&(); // legal
operator int S::*() { return &S::i; } // legal!
operator S*() // legal
};
A `declarator' is the C++ grammar element that leads to things like
arrays, pointers/references to arrays, and function and member
function pointers. Since `declarator's never enter the picture when
it comes to `operator' conversion functions, the C++ grammar simply
doesn't allow the following:
struct S {
operator void (*)(void)(); // error; no function pointers
operator float (&)[3](); // error; no references to array
operator void (Foo::*)(void)(); // error: no member func ptrs
};
>[...] Thus IMHO the goal is beyond the reach. It amazes -- we can do this
>kind of declarations with arguments:
>
>void f( int (Class::*)(void) );
> ~~~~~~~~~~~~~~~~~~~~
>works OK, at least with Borland's C++ 3.1 compiler. But "way closed"
>with function return values and type casts.
I'm not sure I understand the above, but C++ does not restrict
function return types. It *does* restrict the syntax for declaring an
`operator' conversion function. The following is legal:
struct Class { int f(); };
struct S {
int (Class::* convert())() { return &Class::f; }
// `convert' is a member function taking no parameters,
// returning a Class member pointer to a function taking
// no parameters and returning an `int'
};
>I comprehend that my posting is not an answer at all! I can't see why
>there cannot be a compiler that allows parentheses in type constructs
>everywhere. If so, one can try:
>
>operator (int (Class::*)(void)) ();
It's important to understand that a C/C++ declaration is not like a
mathematical expression -- extra parenthesis are not allowed and the
parenthesis don't really imply "grouping" in a declaration. The use
of parenthesis are strictly and completely defined in the grammar when
it comes to type declarations.
(char*) strings[3]; // error
>The answer should lay in the PRECISE AND FORMAL description [...]
>So, I have a felling that the questions of such kind will be steadily
>arising until the standard language grammar will be available. Maybe it
>is a good subject for discussion itself?
What's wrong with the grammar in the ARM and CPL2? I have read
there's some problems with a C/C++ grammar (something about typedefs,
shift/reduce, ... it's on my list of things I don't fully understand
but know I should), but it's certainly precise and complete with
respect to the subject of this thread. I agree C/C++ allows one to
write confusing declarations, but using typedefs instead makes things
more readable. Also see the comp.lang.c FAQ 10.3 about `cdecl'.
This article is crossposted and redirected to comp.std.c++; it seems
further discussion is more appropriate there.
Jamshid Afshar
jamshid@emx.utexas.edu
Author: No Author
Date: No Date Raw View
In one word : missing rules either
- add complexity (if I really need *that feature* , whatever the cost)
- reduce functionnality (if the cost is to high, my program won't do that)
I suppose my algorithms are good, no special feature can turn a bad programmer
into a good one !
I don't think many rules will produce unreadable code - just the opposite -
For everyday job, I use only a very simple subset of syntax rules, but whenever
I need a feature I *make it work*, one way or another. I personnaly prefer to
use a well documented feature of a standardized language - whose details I can
find about in a reference book - than design my own. More : that way is generally
much more efficient and shorter.
Exceptional rules are no problem to me as long those rules won't be used every line
of code. As for C, people I known - successfull programmers of large programs -
don't care much about some C feature, like functional alternative, places where
l-values are legal, use of coma in expressions, preprocessor special ansi design,
ansi headers and typing of function, designing of variable arguments functions, etc.
They don't known about those things and don't care !
But how could you design your own portable printf when need arise without some of
those things.
One last thing : extending a language is not ever adding exception. It can be removing
exceptions too. I think of the subject of nested functions that has already been discussed
in this newsgroup. Allowing nested functions would be a certain amount of work for compiler
writers, but for users it is merely a matter of removing a constraint, as functions are the
last structure (am I right ?) that still can't be nested In C++.
There were many things missing with C. It implied a specific way of thinking.
C is well designed to do simple functional programming.
C++ permit either to use C style or OO style. That is still not all of it. There still
is many other programming styles, for instance implementing Petri nets algorithms,
finite state automatoes, or using Continuation Passing Style is far from efficient
when you do it with C or C++ constraints.
I got the idea a computer language is a tool for making algorithms work, would you care
removing abstract words from english cause 'humans have a limited tolerance to complexity'
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Installers have been written for the VAX, MIPS, i386, SPARC, 68k, and
RS/6000 architectures. Currently, C is the only language with an ANDF
producer. Operating systems supported are Ultrix4, SCO/UNIX, SUNOS,
HP_UX, AIX, and OSF/1 both with integrated kernel and with microkernel.
The runtime performance of code produced by the ANDF technology is
within about 5% of the best native compiler produced code, for selected
benchmarks (including SPECint), and is sometimes better. Application
Programming Interfaces (APIs) currently supported include ANSI C, Posix,
and XPG3. DRA and USL are working on SVID3 support.
3 Current and Planned ANDF Programs
3.1 DRA continues to develop the ANDF technology, under contracts from
OSF and others. Recent code drops (October and November 1992) have
supported a revised spec which is capable of supporting C, C++, Fortran,
and the Pascal family of languages. In addition, ANDF is extensible so
it should be possible to make any extensions needed for additional
languages in an upward compatible way. Currently, C is the only
language with an ANDF producer.
3.2 HP has been sponsoring work at OSF to validate the ANDF technology
by using the DRA tools to port real world applications. It is also
sponsoring the GANDF project, an experimental installer based on the Gnu
C Compiler from the Free Software Foundation. A primary goal of GANDF
is to show that ANDF can be interfaced to existing compiler back-end
technology (with one aim being an installer for the PA-RISC
architecture). This should encourage system vendors to undertake the
production of high quality installers based on their existing high
quality compiler back-ends. In addition, if GANDF turns out to be a
practical way to produce installers, it will become easy to produce
installers, of quality comparable to gcc, for all of the targets that
gcc supports.
3.3 USL has sponsored work at OSF and DRA to support portable software
for their Destiny (System V release 4.2) operating system, as well as
general work in validating the ANDF technology. The ORACLE data base
system is being ported to ANDF as part of this project.
3.4 The GLUE (Global Language support and Uniform Environment) project
is part of the Open Microprocessor Initiative (OMI), which is funded by
the European Esprit program. The global objective of the project is to
use the ANDF technology to provide a common interface between a number
of RISC microprocessor based systems and a set of application software
packages; the idea being to insulate the application software from the
underlying O/S and hardware base, in order to avoid the huge expense
associated with repeated porting from one base to another. [2] It is a
3 year program that started in July 1992 and which is expected to
represent about a 1100 staff-month effort. The following are the main
participants of the OMI/GLUE project:
Company Country
------------------------
Etnoteam Italy
DDC-I Denmark
DRA UK
Harlequin UK
OSF-RI France
Bull France
INESC Portugal
Inmos UK
The OMI/GLUE project includes the following tasks: an F77 producer, an Alpha
Installer, a Formal Specification, an Ada producer, ANDF tools, a Lisp
Producer, ANDF Validation Suite, a software distribution study, a C++
producer, Parallelization extensions for ANDF, an occam producer, and an ANDF
installer for transputers,
3.5 A three-year DARPA-sponsored research program at the OSF RI in Cambridge
started in December 1992. It includes work on ANDF extensions to support
massively parallel processing, primarily in Fortran.
3.6 The ANDF Snapshot program continues. Currently 19 companies are
snapshot licensees.
4. A Brief Summary of Expected ANDF Benefits [3]
4.1 End User Benefits
- Increased availability of software for open systems
- Ability to decouple software and hardware purchasing decisions
- Ease of distribution
- Reduction in training costs when users move from one platform to
another.
- Increased longevity of software investments, since ANDF applications
will run on new hardware that supports ANDF
- Scalability of applications and interoperability of various machine
architectures .
- Reduced need to upgrade an application for new system versions.
4.2 Software Vendor Benefits
- Simplified software development of portable code
- Reduced maintenance cost
- Reduced testing cost
- Reduced manufacturing and distribution costs
4.3 System Vendor Benefits
- Immediate access to an application base for new architectures
- Freedom to create new hardware and software while preserving the
application base.
- Reduced cost to carry a diverse product line with multiple
architectures and operating systems.
5. Credits and Bibliography
For those desiring more information about ANDF, here is a bibliography.
These documents are available from OSF, except as noted otherwise. Some
of the the information and wording of this announcement was extracted
from some of the OSF documents listed below.
[1] OSF Architecture-Neutral Distribution Format Rationale, Anonymous,
June 1991, OSF.
[2] The information in item 3.4 is taken from internal OSF documents by Ira
Goldstein and Jacques Febvre. For further information on the OMI/GLUE
project, contact the project director,
Gianluigi Castelli
Etnoteam
Via Adelaide Bono Cairoli
34-20127 Milan, Italy
phone: + 39 / 2 / 261 621
fax: + 39 / 2 / 261 10755
e-mail: gicas@etnomi.uucp
[3] ANDF, Application Portability, and Open Systems: A White Paper,
Anonymous, December 1991, OSF.
[4] Answers to Commonly Asked Questions about the OSF
Architecture-Neutral Software Distribution Format, Anonymous, February
1991, OSF.
[5] The Structure of ANDF: Principles and Examples: A Technical Paper,
by Stavros Macrakis, January 1992, OSF.
[6] From UNCOL to ANDF: Progress in Standard Intermediate Languages: A
Technical Paper, by Stavros Macrakis, January 1992, OSF.
[7] The ANDF Advanced Technology Program at OSF, by Ira Goldstein, July
1992, OSF.
[8] TDF (Ten15 Distribution Format) Specification, Defense Research
Agency, UK, September 1992, DRA.
[9] OSF's ANDF by Judith S. Hurwitz, October 1991, available as a
reprint from "Unix in the Office" Vol. 6, No. 10, Patricia Seybold's
Office Computing Group.
[10] Protecting Source Code with ANDF, by Stavros Macrakis, November
1992, OSF.
Other references will be forthcoming. Updated ANDF bibliographies will
be posted periodically on the andf-tech@osf.org mailing list.
======================================================================
Richard L. Ford | Open Software Foundation | <richford@osf.org>
~~~~~~~~~~~~~~~ | Research Institute | Phone: +1 617 621 7392
Consultant | One Cambridge Center | Fax: +1 617 621 8696
| Cambridge, MA 02142, USA |
The opinions expressed are my own, and not necessarily those of OSF.
Volume-Number: Volume 30, Number 25
Author: No Author
Date: No Date Raw View
From one point of view only legal transformations from derived to base
classes have occured, so object identity must be maintained -- you're still
referring "'to the same object'" as you originally were referring to.
Author: No Author
Date: No Date Raw View
In terms of object identity:
Does pb refer to the same object as &d?
Yes because B is a superclass of D
Does pc refer to the same object as &d?
Yes because C is a superclass of D
Does pa1 refer to the same object as pb?
Yes because A is a superclass of B
Does pa2 refer to the same object as pc?
Yes because A is a superclass of C
Does pa1 refer to the same object as pa2?
Yes because the chain of object identity has been maintained
No because in C++ the two base objects "are distinct"
Conclusions?
Pointers do not model object identity in C++. Template classes
that assume pointers model unique identity of objects will not
work in general. If the programmer of a class is to correctly model
object identity, they need to do so by how they program their class.
Trying to make the language maintain a one-to-one correspondence
between pointers and object identity is not possible. Issues
of "type of pointer" "type of object" "type of derivation" "empty classes"
"vbases" "vptrs" "MI" etc all become pertinent to when or when not, how and
how not pointer comparisons should work in C++. "General" rules are doomed to
failure, because in general there is not a one-to-one correspondence
between pointers and object identity in C++.
Author: No Author
Date: No Date Raw View
I strongly support this idea. Friends are great but there are
close friends, friends and aquaintances with the latter two usualy more
numerous than the former. The idea is simple to implement and requires
no new syntax so why not.
Nick Hounsome
Author: No Author
Date: No Date Raw View
In the case of downcasting from a base to a derived class
you CANNOT know the alternatives, you CANNOT know what the
derived types are,m because THAT LACK OF KNOWLEDGE IS
FUNDAMENTAL to the idea of inheritance.
>
>>
>> I am against using, in general programming,
>> DOWNCASTING or run-time type information to defeat the type system.
>>
>I just don't understand!
>Run time type check is a facillity to prevent careless
>downcast to defeat the type system.
>How can you say that it is used in general
>programming to defeat the type system?
Because if you are using it in *domestic* programs to downcast
safely, you are using it to downcast, and downcasting is defeating
a promise made by the concept of inheritance: that promise is
called the OPEN/CLOSED principle. It is the cornerstone of
object oriented design (well, actually, class-oriented design).
It makes the promise that an algorithm applied to
a class B will continue to work for ALL classes D1, D2, D3
where D1, D2, etc are derived fomr B.
The way this promise is enforced is to hide ALL
details of D1, D2, D3 etc other than those shared in
class B from the algorithm.
If you downcast from the base class B you are learning
something about, say, class D1 that you weren't supposed to know.
If you use that knowledge, you will become unstuck.
Let me give you an example. Suppose class D1 has a function
f() while B has no such function. You have an algorithm that
downcasts to D1 from B and calls f().
But then you change D1 to NOT have a function f().
Suddenly, the algorithm FAILS. (It won't even compile).
[Too bad if the algorithm was locked away in binary form,
then it will fail at link time, or if linkage is dynamic, who knows?]
Now you see you have caused an algorithm which, by its
declaration ONLY DEPENDED ON THE INTERFACE (and semantics :-)
of class B to fail --- BY MODIFYING D1, which is derived from
B. You have VOIDED THE OPEN/CLOSED PRINCIPLE by using a downcast.
Now again: before we can discuss when and how to use RTTI, I need
you to understand that the OPEN/CLOSED principle is voided
by using downcasting and to agree that this is not desirable.
I need you to see the issue IS NOT ABOUT THE SAFETY OF DOWNCASTING.
The issue is, how can one carefully discriminate the legitimate
use of RTTI in *meta-domestic* systems, and maybe in
*foreign* systems, from its illegitimate use for
downcasting in *domestic* systems.
>
>> I agree that in Debuggers and other such programs
>> these facilities are essential, indeed, you need much more
>> than a mere safe downcast or run-time type code. In a debugger,
>> for example, you need in effect run-time access
>> to the complete declaration and definintion of each class in
>> the whole program!
>>
>A simple type id can be a key for a debugger to access to the complete
>declaration and definintion of each class in the whole program. We are not
>necessary to include the complete type information at run time.
You do if the debugger is any good.
>
>> C++ does NOT have facilities at present to do this.
>> I am NOT against adding them. But I would be against using these
>> facilities in the general programming context for which C++
>> was intended and where such mechanism are *dangerous*.
>>
>Again, I can't understand.
>Run time type check is not a dangerous mechanism.
Run time type information is INHERENTLY DANGEROUS,
because it can provide access to information that the type
system has DELIBERATELY HIDDEN. The only reason you want run-time
information is that YOU DONT HAVE INFORMATION THE SYSTEM HAS
HIDDEN FROM YOU DELIBERATELY, PREICSELY BECAUSE ANY ATTEMPT
TO USE THAT INFORMATION IS UNSAFE TO USE.
The fact that you can use it to convert a base class
does not make that conversion safe. Just because you get back
a pointer you know is the right type DOESN'T mean
you were entitled to use that pointer.
>On
>the contrary, it is used prevent potential dangers.
>
>> Clearly, for example, a debugger which allows you
>> to modify instances of a class breaks encapsulation!
>> It breaks almost every principle you can think of.
>> It is meant to: you use the debugger when a more important
>> thing is already broken : your program :-)
>>
>Here, you goes too far. A debugger can break every principle of encapsulation
>and protection only through low level programming facillities (e.g. the bitwise
>and bytewise read/write, enforced typecasting between different types, machine
>addresses, etc.).
You confuse 'breaking the system' with causing a fault.
To cause a fault, you need only write somewhere in memory
that you weren't meant to. To do that you MUST use a cast.
So casts are bad. (Conversions are not, however).
A 'hacker' breaks system security when e accesses the system.
That doesn't mean the system is 'messed up', or the file system
destroyed. None-the-less, the system is *broken* when security
is breached *even if no damage is done*.
In the case of downcasting the problem is the same as for
any old casting: you have access to information you shouldn't have.
The reason you shouldn't have it is that if you do you MIGHT
proceed to destroy the system integrity, by breaching
promises the system has made.
For example, if I give you an animal pointer,
and it has read only functions ONLY, I expect the object to
remain unchanged.
If you cast it to a Mammal, which has mutator functions,
and proceed to mutate it, I will be very annoyed. I want the
system to PROMISE ME YOU CANT DO THAT, at least not privately.
>But a debugger can never break any principle of encapsulation
>and protection only through run time type check.
OF COURSE IT CAN. The debugger has access to the
private data of an object. The debugger is not a member function
of the object. THEREFORE, unequivocably, the debugger has broken
the encapsulation of the object (even if it is a benign debugger
and wont abuse the priviledge).
>Remember: run time type checking does not allow to cast objects
>which are actually of different types.
Agreed. But it facilitates casting. Casting is bad.
(Usually) Since we dont want to cast things, we dont need to
do it safely!
>
>Even we stick to homogeneous programming, we still need run time type checking.
>One of your reason against the concept of "thisclass" is that it needs run time
>type checking, which you view as a disadvantadge. "thisclass" is just a
>facillity to describle homogeneous data structure.
Yes. I'm not necessarily against 'thisclass', I merely pointed out
that it has some disadvantages. Requiring RTTI is a disadvantage
because we dont yet have it :-)
>
>Okay, let's get rid of the concept of "thisclass" for the time being. Now, is
>it true that run time type checking is no longer needed for homogeneous data
>structure? No.
We still disagree: for domestic systems, yes, RTTI is NEVER
needed. I've never needed it. I always know what types I'm working with!
[Actually, i cheat a bit in template classes to achieve code reuse,
I sometimes cast void* to T*, but is not NECESSARY, just expedient]
>Without covariant type specification (now, we come to our
>original subject) in derived classes, we still have to run time type check the
>type of arguments in derived classes in order to prevent any violation.
NO, you have to accept the restriction of single dispatch.
The ONLY object you know the type of is the *this object.
(And any others passed by value).
>Let's
>consider a homogeneous animal collection:
>
> class Animal;
> class AnimalGroup
> { protected:
> Animal * animals;
> public:
> virtual void accept (Animal *ap) {...};
> ...
> };
>
>Since it is a homogeneous collection, it should contains animals of the same
>type. The concept of "same type" is relatively dependend on what the class
>designer means.
No, quite wrong. Same type means 'common properties
of all animals'. It SPECIFICALLY excludes you knowing about
whether the animal has webbed feet. Because snakes dont have
feet, so its not a property common to all animals.
>Suppose the same type" is based on the *family* according to
>the systemtic zoology. Then the collection should be of all dogs, or all cats,
>etc.
Then you should have a collection of all dogs, or all cats,
not all animals.
This is why some people like templates a lot.
Now you have further example of a serious problem, but I will
simplify it.
The problem is why you proposed 'thisclass' and is a real problem.
It is a problem for which RTTI is the wrong solution,
but never-the-less is the best we will get for a while.
We really need multiple dispatch.
class Animal {
int mate(Animal&);
};
class Dog : Animal {
int mate (Animal&);
};
We REALLY want Dog::mate(Dog&), but we cant have it.
This is a flaw in Object Oriented Programming IMHO.
The solution requires multimethods which are inherently
functional.
--
;----------------------------------------------------------------------
JOHN (MAX) SKALLER, maxtal@extro.ucc.su.oz.au
Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Author: No Author
Date: No Date Raw View
Section 2.2.3 Signals and Interrupts
Functions shall be implemented such that they may be interrupted
at any time by a signal, or may be called by signal handler, or
both, with no alteration to earlier, but still active, invocations'
control flow (after the interruption), function return values,
or objects with automatic storage duration. All such objects shall
be maintained outside the \fIfunction image\fR (the instructions that
comprise the executable representation of a function) on a
per-invocation basis.
End of quotation
The decision to explicitly address signals in the standard
was not a trivial one for X3J11, as I recall, since our
execution model included only one execution thread. The
requirement above was intended, I think, to provide the
minimum necessary to support common uses of signals on Unix,
and to allow thread simulations to be built on top of C.
I suspect that this is one place where it would not be advisable
for X3J16 to take a different stance than X3J11. If X3J16
is not persuaded to make such a requirement, it should probably
be noted in the "Differences from ANSI C" section.
Tom Kelly (416) 922-1937
SCO Canada, Inc., 130 Bloor St. W., Toronto, Ontario, Canada
{utzoo, utcsri, uunet}!scocan!tom or tom@sco.com
Author: No Author
Date: No Date Raw View
.... x and y are of type double ....
pow(x,y) A domain error occurs if x=0 and y<=0, or if x<0 and y is not an
INTEGER.
^^^^^^^
>
> There IS a difference IMHO between pow and operator!, the
>former is a library function and NOT part of the language definition,
>you can always replace a library function. That is not always
>the case with an operator.
The C++ standard must after all standarize <new.h> so why not make
small changes to <math.h> ?
Or they could say that <math.h> might contain overloaded versions
of the functions it contains, but without requiring them.
(float sin(float),long double sin(long double)...)
If the C++ standard is going to leave the the contents of <math.h> undefined
there's nothing that would prevent an implementation from adding
double pow(double,int) today.
>
> We could *insist* that it is the case, enabling user control
>of the operator (it is just a smart macro, we insist a!b => pow(a,b),
>and the compiler does NOT optimise). Or we can just leave it
>up to the vendor. But then we need a proper spec.
>>
>>Having said that I think there are two problems here and it would be
>>easier if they were treated separately:
>>1: How(and if) the pow-function should be overloaded.
>
> I think we can already overload pow. Just write pow(double,int).
>(It is a C++ function, and pow(double,double) is a C function, but that
>should be OK I think).
Correct, Bjarne does this in The C++ Programming Language, but I was
talking about the functions in <math.h> and not user-defined ones.
>
>>2: A simpler notation for the pow-function.(An operator! or operator~ or...)
>>
>
> It is not just notation if the compiler recognizes it and
>the vendor is free to implement it---and take control away from the user.
>Remember non-class operators cannot be overloaded.
Correct: It's a simpler notation and giving up the ability to replace
the function with a correct one (some implementors actually have problems
with getting one pow-function right).
>
>>1:
>>
>>In my opinion it would be good to have double pow(double,int) in math.h
>>because:
>
> Perhaps pow(double,long) is safer?
>
>>o The reason we don't have it is C's lack of overloading.
>>o A simple implementation takes 20 seconds to write.
>>o It will increase performance and precision on most computers.
>
> That depends. I think 486 FPU might do pow(double,double)
>faster than any other method, depends on the the algorithm they use.
>[It is microcoded anyhow]
I find it hard to believe that pow(x,(double)2) is faster than x*x.
>
>But again, having pow(double,int) defined doesn't REQUIRE a different
>method, it ALLOWS for it: what it requires is that the answer BE CALCULATED
>without error.
But the point I was trying to make is that it's already required.
It might however be easier to write a pow(double,int) because
you know that integers are integers, so you can safely omit the test.
[Deleted text]
[BTW operator@ is already in The C++ Programming Language :-) ]
Author: No Author
Date: No Date Raw View
AT&T cfront 3.01 : does not accept default arguments
Borland C++ 3.0 : considers default arguments ok
question 2:
-----------
How can you specify friend functions for a template class with non-type
arguments ? According to ARM p.347, function templates may use only type
arguments.
This would mean that I cannot define friend functions for class templates,
as indicated in the example below:
| template <class T, int sz>
| class stack {
| friend ostream& operator<< (ostream& os, stack<T,sz>);
| public:
| stack () { index = 0; }
| void push (T elem) { tab[index++] = elem; }
| T pop (void) { return tab[--index]; }
| private:
| T tab[sz];
| int index;
| };
|
|
| // The following is illegal according to ARM, but is really what
| // is needed
| template <class T, int sz>
| ostream& operator<< (ostream& os, stack<T,sz> st)
| {
| for (int i=0; i<st.index; i++)
| cout << st.tab[i] << endl;
| }
Correct me if I'm wrong, but it seems to me that one cannot specify (in
generic terms) the type of the stack in the friend function. Is there a
work-around for this kind of friend functions (after all, overloading the
output operator is not that special, and I would expect that it should be
possible to do this).
herman
-----------------------------------------------------------------------------
Herman Moons Katholieke Universiteit Leuven
Dept. of Computer Science
Tf : +32 (16) 20.10.15 ext 3642 Celestijnenlaan 200A
Fax: +32 (16) 20.53.08 B-3001 Heverlee-Leuven
Belgium
e-mail: herman@cs.kuleuven.ac.be
-----------------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
AT&T cfront 3.01 : does not accept default arguments
Borland C++ 3.0 : considers default arguments ok
question 2:
-----------
How can you specify friend functions for a template class with non-type
arguments ? According to ARM p.347, function templates may use only type
arguments.
This would mean that I cannot define friend functions for class templates,
as indicated in the example below:
| template <class T, int sz>
| class stack {
| friend ostream& operator<< (ostream& os, stack<T,sz>);
| public:
| stack () { index = 0; }
| void push (T elem) { tab[index++] = elem; }
| T pop (void) { return tab[--index]; }
| private:
| T tab[sz];
| int index;
| };
|
|
| // The following is illegal according to ARM, but is really what
| // is needed
| template <class T, int sz>
| ostream& operator<< (ostream& os, stack<T,sz> st)
| {
| for (int i=0; i<st.index; i++)
| os << st.tab[i] << endl;
| return os;
| }
Correct me if I'm wrong, but it seems to me that one cannot specify (in
generic terms) the type of the stack in the friend function. Is there a
work-around for this kind of friend functions (after all, overloading the
output operator is not that special, and I would expect that it should be
possible to do this).
herman
-----------------------------------------------------------------------------
Herman Moons Katholieke Universiteit Leuven
Dept. of Computer Science
Tf : +32 (16) 20.10.15 ext 3642 Celestijnenlaan 200A
Fax: +32 (16) 20.53.08 B-3001 Heverlee-Leuven
Belgium
e-mail: herman@cs.kuleuven.ac.be
-----------------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
For purposes of argument matching, a nonstatic member function
is considered to have an extra argument specifying the object
for which it is called.
[...]
Where a member of a class X is explicitly called for a pointer
using the -> operator, this extra argument is assumed to have
type const X* for const members, volatile X* for volatile
members, and X* for others. Where the member function is
explicitly called for an object using the . operator or the
function is invoked for the first operand of an overloaded
operator, this extra argument is assumed to have type const X&
for const members, [etc.]
So, in so far as the standard is based on E&S, this would appear to
be standard and not implementation-specific.
--
Anil A. Pal, Silicon Graphics, Inc.
pal@wpd.sgi.com (415)-335-7279
Author: No Author
Date: No Date Raw View
The type of the return value of (new char[40]) may indeed be
(char *) rather than (char []), but the object is still an array.
Daniel R. Edelson | I am not the Daniel Edelson who works in Artificial
edelson@sor.inria.fr | Intelligence at Northwestern University.
daniel@cis.ucsc.edu |
Author: No Author
Date: No Date Raw View
1. New book of Bjarnes or Lipmmans
2. Mats Henricson "Coding standards of Ellemtel" (in Swedish)
---------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
3. Tom Cargill "C++ Programming Style" in the C++ Journal, vol 1 #3
-------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
4. About a year ago, an issue of Apple's d e v e l o p magazine
had an article by Jack Palevich on C++ style. Variants of
the style described are used by several groups in Apple.
----------------------------------------------------------
Author: No Author
Date: No Date Raw View
5. "Unofficial C++ Style Guide" by David Goldsmith and Jack Palevich, from
develop Magazine, Issue 2, April 1990. (develop is a technical journal
published by Apple. I think back issues are available from APDA.)
-------------------------------------------------------------
Author: No Author
Date: No Date Raw View
6. "Advanced C++ Programming Styles and Idioms" by James O.Coplien
addison wesley, isbn:0-201-54855
---------------------------------------------------------------------------
Author: No Author
Date: No Date Raw View
7. Contact Dr. T. Muldner at Acadia University. His email address:
solid@aucs.acadiaU.Ca I think he has some papers.
-------------- LAST ENTRY IN THE LIST (long) ----------
Author: No Author
Date: No Date Raw View
PART# 3
==============================================================================
SECTION: Style guidelines
==============================================================================
Q61: What are some good C++ coding standards?
A: Thank you for reading this answer rather than just trying to set your own
coding standards. But please don't ask this question on Usenet. Nearly every
software engineer has, at some point, felt that coding standards are or can be
used as a `power play'. Furthermore some people on Usenet report that attempts
to set C++ coding standards have been made by those unfamiliar with the
language and/or paradigm, so the standards end up being based on the state-of-
the-art when the standards setters where coding. These generate an attitude of
mistrust for coding standards. Obviously anyone who asks this question on
Usenet wants to be trained so they *don't* run off on their own ignorance, but
nonetheless the answers tend to generate more heat than light.
Coding standards, in my opinion, are a necessary evil. In large organizations,
they are neither demeaning, nor do they turn programmers into mindless idiots.
They merely delineate semi-common ground so people can read and understand each
others' code with minimal fuss (C++ is a flexible enough language that you can
even make it `look' like Pascal, Ada, Smalltalk, or even Lisp; simply saying
``Use C++ as it was meant to be used'' is insufficiently vague).
The success of traditional programming techniques is due in part to an
implementation CULTURE which is so pervasive that no one even knows it's there
[Ref: B. Leathers, `After The Divorce, Reflections on using Eiffel at Cognos',
proceedings SOOPPA, 1990]. Most people have certain `intuitions' about
structured programming, since they've been immersed in it for their entire
professional careers. OOP, at present, lacks this `culture', so the structure
and form given by coding standards can help start us along (no one doubts that
functionality is more important then form, but we still need, to a certain
extent, both).
Coding standards do not make non OO programmers into OO programmers. Only
training and experience do that. But coding standards do tend to avoid the
petty fragmentation that occurs in organizations that attempt to coordinate the
activities of diverse groups of programmers.
One more bit of advice: you really want more than a coding standard. The
structure provided by coding standards gives neophytes one less degree of
freedom to worry about (besides the obvious logistical benefits of coordinating
code written by many people), however pragmatics go well beyond pretty-printing
standards. We actually need a consistent *philosophy* of implementation. Ex:
strong or weak typing? references or ptrs in our interface? stream I/O or
stdio? should C++ code call our C, or vise versa? how should we handle
exceptions? should we use ABCs? polymorphism? inheritance? classes?
encapsulation?
Therefore coding standards are too `low level' for what is needed: a standard
for *detailed-design*. How can we get this? I recommend a two-pronged
approach: training and libraries. Training provides ``intense instruction'',
and a high quality C++ class library provides ``long term instruction''. There
is a thriving commercial market for both kinds of ``training''. Advice by
organizations who have been through the mill is commonly: Buy, don't build.
Buy libraries, buy training, buy compilers. Companies who have attempted to
become a self-taught tool-shop as well as an application/system shop have found
success difficult.
Again: I am not saying that coding standards are `ideal', or even `good'; only
that they're necessary in the kind of organizations/situations described above.
The following questions provide some basic guidance in conventions and styles.
==============================================================================
Q62: Should our organization determine coding standards from our C experience?
A: No matter how vast your C experience, no matter how advanced your C
expertise, being a good C programmer does not make you a good C++ programmer.
C programmers must learn to use the `++' part of `C++', or the results will be
lackluster. People who want the `promise' of OOP, but who fail to put the `OO'
into OOP, are fooling themselves, and the balance sheet will show their folly.
C++ coding standards should be tempered by C++ experts. Asking comp.lang.c++
is a start (but don't use the term `coding standard' in the question; instead
simply say, `what are the pros and cons of this technique?'). Seek out experts
who can help guide you away from pitfalls. Get training. Buy libraries and
see if `good' libraries pass your coding standards. Do not set standards by
yourself unless you have considerable experience in C++ (having no standard is
better than having a bad standard; improper `official' positions `harden' bad
brain traces). As I said in the last question, there is a thriving market for
both C++ training and libraries.
One more thing: any time demand for something is high, the potential for
charlatans increases. Look before you leap. Ask for reviews from past
students as well, since not even expertise makes someone a good communicator.
==============================================================================
Q63: Why should I declare locals in the middle of a fn rather than at the top?
A: Different people have different opinions about coding standards. However
one thing we all should agree on is this: no style guide should impose undue
performance penalties. The real reason C++ allows objects to be created
anywhere in the block is not style, but performance.
An object is initialized (constructed) the moment it is declared. If you don't
know how to initialize it until half way down the fn, you can either initialize
it to an `empty' value at the top then `assign' it later, or initialize it
correctly half way down the fn. It doesn't take much imagination to see that
it's cheaper to get it right the first time than it is to build it once, tear
it down, then rebuild it again. Simple examples show a factor of 350% more
freestore allocations for simple classes like String. Your mileage may vary,
and surely you'll get less that 300+% degradation on the overall system, but
you'll certainly get degradation. *Unnecessary* and *needless* degradation.
A common retort to the above is: ``we'll provide `set' methods for every datum
in our objects, so the cost of construction will be spread out''. This is
worse than the performance overhead, since now you're introducing a maintenance
nightmare. Providing `set' methods for every datum is tantamount to public
data. You've exposed your implementation technique to the world. The only
thing you've hidden is the physical *names* of your subobjects, but the fact
that you're using a List and a String and a float (for example) is open for all
to see. Maintenance generally consumes far more resources than runtime CPU.
==============================================================================
Q64: What source-file-name convention is best? `foo.C'? `foo.cc'? `foo.cpp'?
A: Most Un*x compilers accept `.C' for C++ source files, g++ preferring `.cc',
and cfront also accepting `.c'. Most DOS and OS/2 compilers require `.cpp'
since DOS filesystems aren't case sensitive. Some also advocate `.cxx'. The
impact of this decision is not great, since a trivial shell script can rename
all .cc files into .C files. The only files that would have to be modified are
the Makefiles, which is a very small piece of your maintenance costs.
==============================================================================
Q65: What header-file-name convention is best? `foo.H'? `foo.hh'? `foo.hpp'?
A: The naming of your source files is cheap since it doesn't effect your source
code. Your substantial investment is your source code. Therefore the names of
your header files must be chosen with much greater care. The preprocessor will
accept whatever name you give it in the #include line, but whatever you choose,
you will want to plan on sticking with it for a long time, since it is more
expensive to change (though certainly not as difficult as, say, porting to a
new language).
Almost all vendors ship their C++ header files using a `.h' extension, which
means you can reliably do things like:
#include <iostream.h>
Well, *almost*. There are one or two vendors that provide <iostream.hpp>. A
few #ifdef's, suffice. There are also tools that recognize the language of a
file by its extension rather than its contents (gnu emacs looks in the first
few lines for a string magic token in a comment identifying the language).
Some of these extension-based tools use `.hh' or `.H' to identify C++ headers,
however most of the world is leaning toward `.h' for C++ headers. C++ specific
information in a `.h' that is to be shared with a C compiler can be #ifdef'd
using:
#ifdef __cplusplus
// ... C++ specific stuff here ...
#endif
==============================================================================
Q66: Are there any lint-like guidelines for C++?
A: Yes, there are some practices which are generally considered dangerous.
However none of these are universally ``bad'', since situations arise when
even the worst of these is needed:
* a class ``X''s assignment operator should return ``*this'' as an ``X&''
(allows chaining of assignments)
* a class with any virtual fns ought to have a virtual destructor
* a class with any of {dtor, assignment-op, copy-ctor} generally needs all 3
* a class ``X''s copy ctor and assignment op should have ``const'' in the sig:
``X::X(const X&)'' and ``X& X::operator=(const X&)'' respectively
* always use initialization lists for class sub-objects rather than assignment
(the performance difference can be substantial [as in 3x!])
* assignment operators should start by testing if `we' equals `them'; ex:
X& X::operator=(const X& x)
{
if (this == &x) return *this;
//...normal assignment duties...
return *this;
}
* ``a+=b'' and ``a=a+b'' should generally mean the same thing; ditto for other
identities that builtin types have (ex: a+=1 and ++a; p[i] and *(p+i); etc).
This can be enforced by writing binary ops using the `op=' forms; ex:
X operator+(const X& a, const X& b)
{
X ans = a;
ans += b;
return ans;
}
This way the `constructive' binary ops don't even need to be friends, but it
is sometimes possible to more efficiently implement common ops (ex: if `X'
a `String' and `+=' has to reallocate/copy string memory, it's better to
know the eventual length from the beginning).
See Stroustrup/C++ Programming Language/Second Edition/`Rules of Thumb'/p.10
------------------------------------------------------------------------
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Dimitri Konstantas | UUCP : mcvax!cernvax!cui!dimitri
Centre Universitaire d'Informatique | EARN : dimitri@cgeuge51.bitnet
University of Geneva | X400 : dimitri@cui.unige.ch
12 rue du Lac | Tel. : +41 (22) 787-6586
CH-1207 Geneva,SUISE | Fax. : +41 (22) 735-3905
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Author: No Author
Date: No Date Raw View
Author: No Author
Date: No Date Raw View
Is this an indication that there are no programming style rules for C++ ?
I would really be surprised!!
So once more, Please, if you know of any reference for any C++ programming
style rules I would appreciate if you could send me a message.
I will post a summary when I get some replies back.
Thank you in advance
dimitri
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Dimitri Konstantas | UUCP : mcvax!cernvax!cui!dimitri
Centre Universitaire d'Informatique | EARN : dimitri@cgeuge51.bitnet
University of Geneva | X400 : dimitri@cui.unige.ch
12 rue du Lac | Tel. : +41 (22) 787-6586
CH-1207 Geneva,SUISE | Fax. : +41 (22) 735-3905
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Author: No Author
Date: No Date Raw View
extern "C" {
static void (*f)();
};
Since any declarations/definitions are gramaticly allowed inside an extern
construct. The following may also be valid:
extern "C" static void (*f)();
I don't know whether current implementations support this (I have nothing
to test this on), but they should. Another use for this flexibility might
be to provide a way to define resources for the Macintosh within the C++
source (i.e. extern "resource ICON,128" {....}). Just a thought.
(Note: I am refering to AT&T 2.1, not ARM)
-- Ben Schreiber
bs@cs.brandeis.edu
Author: No Author
Date: No Date Raw View
I have successfully implemented Boolean data types in several large
projects (100K+ lines of C++) at the last two companies I have worked
for. If you set it up right, you do get the type-safety without the
performance penalty. In most cases, the biggest concern was size -
could we get a Boolean class that would have size == 1 byte (the minimum)
and align on single-byte boundaries when packed in structures. The
answer is... depends on the architecture. Here is what I usually end
up with:
class Boolean {
unsigned char value;
friend int operator== (Boolean left, Boolean right);
friend int operator!= (Boolean left, Boolean right);
public:
Boolean() {}
Boolean(int i) { value = ((i) ? 1 : 0); }
operator int() const { return (int) value; }
};
inline int operator== (Boolean left, Boolean right)
{ return left.value == right.value; }
inline int operator!= (Boolean left, Boolean right)
{ return left.value != right.value; }
// defined in the source file as initialized to 0 and 1, respectively
extern const Boolean FALSE;
extern const Boolean TRUE;
Notice that initialization by int is allowed (via constructor),
but assignment is not (no operator=(int)). There are some pitfalls
with this approach, however:
1) The type name Boolean sometimes collides with "helpful" libraries
that *just know* you will need a type called Boolean that is a
typedef'd unsigned char. The X toolkit (Xt) is a prime offender.
Folks, what's the point of sticking the Xt prefix on 95% of the
types defined, and skipping the 5% most likely to collide with
an application's own types?
This can be worked around by simply calling your Boolean something
else, like TBoolean (Tom's Boolean :^), and undefining TRUE and FALSE
at the beginning of the header file (if they were defines and not an
enum).
2) The constant values TRUE and FALSE are globals that are initialized
via constructor, and thus cannot be safely used in other global
constructors. Buckle up for safety...
All in all, though, the good outweighs the bad. One other reason that I
usually settle on the class approach for Boolean types is that I often
need many other similar types - for instance Status (SUCCESS or FAILURE) -
which are not compatible with Boolean and can cause trouble if they
are assigned to each other. (Of course, Status is defined as int by
the X11 Xlib.h header file - don't get me started on graduate-student
software again).
Hope this was somewhat helpful - I feel better now.
Thomas Smith
Elan Computer Group, Inc.
(415) 964-2200
tom@elan.com, ...!{ames, uunet, hplabs}!elan!tom
Author: No Author
Date: No Date Raw View
Anybody who can not handle this "seam" should be programming in LOGO.
Author: No Author
Date: No Date Raw View
In the case of an overloaded "x->", "x->y" would not become "x.y" if
"x" was a structure instead of a pointer.
Responses? Problems? Opinions?
jim miller
jamiller@hpmpeb7.cup.hp.com
(a.k.a James A. Miller; Jim the JAM; stupid; @!?$$!; ... )
Anything I say will be used against me ...
But my company doesn't know or approve or condone anything of mine here.
Author: No Author
Date: No Date Raw View
The issue then becomes what the compiler should do.
It appears impractical for the compiler to implement the programmer's
notion of const (how is this notion communicated?). This leaves the
alternatives of doing nothing, or implementing the storage notion of
const, which the programmer can circumvent as necessary. Are there
other alternatives?
I contend that the cases where storage const is overly restrictive are
few and can be well isolated, making them suitable candidates for
explicit casts. I definitely prefer this situation to the alternative
where the compiler essentially punts on const enforcement.
--
Anil A. Pal, Silicon Graphics, Inc.
pal@sgi.com (415)-335-7279
Author: No Author
Date: No Date Raw View
Switch Ranges
=============
A GNU C++ extension to the switch statement permits range specification
for case values. For example, below is a concise way to print out
a function parameter's "character class:"
print_char_class (char c)
{
switch (c)
{
case 'a'..'z': printf ("lower case\n"); break;
case 'A'..'Z': printf ("upper case\n"); break;
case '0'..'9': printf ("digit\n"); break;
default: printf ("other\n");
}
}
Duplicate, overlapping case values and empty ranges are detected and
rejected by the compiler.
--
Mike Bolotski VLSI Laboratory, Department of Electrical Engineering
mikeb@salmon.ee.ubc.ca University of British Columbia, Vancouver, Canada
Author: No Author
Date: No Date Raw View
``A name first declared by a friend declaration
belongs to the global scope.''
Author: No Author
Date: No Date Raw View
``If a class or function mentioned as a friend has not
been declared its name is entered in the same scope
as the name of the class containing the declaration.''
Clearly these conflict, particularly in the presense of local and
nested classes. Is anyone at AT&T willing to bless rule or the other?
Daniel Edelson
daniel@cis.ucsc.edu
Author: No Author
Date: No Date Raw View
- Look at Eiffel. They do this with some sort of type attribute called
something like "SAME AS", so you could declare you are returning an
object the same type as one of your arguments.
This works because I believe Eiffel's implementation includes class ids
in objects, but I could be wrong.
- It appears to be hard to solve this problem without dynamic class ids.
- Most C++ classes relevant to this need /have\ dynamic class ids -- their
virtual function table addresses! Now, this does not help much when dealing
with persistent objects, but is it worth a shot?
I have intentionally not given details on my thoughts, to prevent undue noise
on the net. I'd be happy to work this out some more if anyone wants (I may
do that anyway!).
Jim Heliotis
Rochester Institute of Technology
Rochester, NY 14623-0887
jeh@CS.RIT.EDU
{allegra,seismo}!rochester!rit!jeh
Author: No Author
Date: No Date Raw View
As you said this is a tedious task for the programmer and I would propose
a construct such as:
class Collection {
public:
virtual WHATEVER_CONCSTRUCT_MEANING_THE_CLASS_OF_RECEIVER * Copy();
};
With such an approach you still get type checking and you don't have to
rewrite the same line for each class in the subclass hierarchy. You would gain
a lot and could then write truly generic behaviors. This would be a good
starting point for reusable classes. The same idea could be extended for
arguments if needed.
--
Franck BOISSIERE boissier@irisa.irisa.fr
Prototyping Lab Manager boissier@ccettix.UUCP
C.C.E.T.T. B.P. 59 boissier%irisa.irisa.fr@uunet.uu.net
35512 CESSON SEVIGNE CEDEX FRANCE