🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by Valentin Bonnard Wed, 13 Mar 1996 04:23
Re: Some ideas about C++ and a question
#3649
Author: Valentin Bonnard
Date: Wed, 13 Mar 1996 04:23
205 lines
8494 bytes
[Note: I have tried to post normally this followup, but it seam it 
didn't work; this follows news:4hdctd$r1p@engnews1.Eng.Sun.COM (Steve 
Clamage's article) Please remove this note before posting. ]

clamage@Eng.Sun.COM (Steve Clamage) wrote:
>Valentin Bonnard <bonnardv@pratique.fr> writes:
>
>>I have 4 ideas about C++ and a question.
>
>>1) String literals
>>~~~~~~~~~~~~~~~~~~
>>String literals should be const char* instead of char* (if it is not
>>already the case).
>
>Yes, it is clearly the "right" thing to do, but it is not the case
>for the same reason it is not the case in Standard C: it would break
>too much existing code to make the change.

Perhaps, but in C void* converted to anything* and it's not the case in C++: this broke more C code (I think, or a least more of my old C code) then what I propose.

Or could it be a compiler option (that all compilers should have) to make string literals char* ?


>>2) Placement operators
>>~~~~~~~~~~~~~~~~~~~~~~
>>class Object {
>>        void    operator+ // or / or whatever
>>                         (Object& result, const Object& b) const;
binary (compute *this + b, put the result in 'result')
>>        void    operator* (Object& result) const;     #2
unary (compute *(*this), put the result in 'result')
>>        Object  operator* (const Object& result) const; // old one
                                           ^^^^^^ ops! should be named b
binary (compute *this + b, return the result)
>>}
>
>>should be called respectively by:
>>a = b + c;
>
>>and a = *b;
>
>>and (old one) a*b;
>
>>This will solve the [well-known] problem of copying the result into a temporary.
>>The compatibility will be preserved since old syntax will be allowed to.
>
>You will have to present this idea in more detail. I can't figure out
>what you are proposing. It looks like you want the function marked #2
>to be some form of unary dereferencing operator, but that would change
>its existing meaning of a member binary (multiplication) operator.

The story begin with a class Object for the construction and destruction is not trivial (and take some time):

Object  a, b, c;
a = b @ c;

where @ is one of: + - * / % & | ^ && || etc... (but not one of: += -= *= /= %= &= |= ^=)

I want to be able to write (using the friend notation to make it a little more clear):
void    operator @ (Object& result, const Object& a, const Object& b);

instead of 
Object    operator @ (const Object& a, const Object& b);

The definition would become (for example):

void    operator @ (Object& result, const Object& a, const Object& b)
{
    result = a;
    result @= b; // direct operation
}

rather than
Object    operator @ (const Object& a, const Object& b)
{
    Object result = a;
    result @= b;

    return Object;      // temporary created with copy constructor, Object deleted,
}                       // then temporary copied into a, and temporary deleted

The old style should still be allowed, and the operator signature is clearly distinct from the one I propose.

For unary operators, the idea is exactly the same, but it's a bit more difficult to see if it's a binary operator or a unary operator because my syntax and an argument:
(where @ is one of ! ~ unary * etc...)

Object  operator @ (const Object&); // again friend version instead of member version
become
void    operator @ (Object&, const Object&); // unary [2]

The problem with * is that the [2] is difficult to distinguish from
Object  operator * (const Object&, const Object&); // binary *, return the result

But my operator return void, so it could be used as an indication: I don't think many people currently have code with
void operator * (Object&, const Object&); // I think this is currently legal
and who write a * b; where a will be modified !

This king of strange code would break if my proposal was accepted for unary operators, but I really don't think it is very serious.

>>3) Use of explicit keyword
>>~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>>void    foo (explicit Derived* object) ...
>
>Evidently you want this to mean that "*object" is of type "Derived"
>and not of any type derived from "Derived". I guess I don't see
>the utility of the declaration. You can create a type which cannot be
>derived from, if that is what you want. If you don't want that, I
>don't see why the author of "foo" wants to be sure no derived type
>is ever passed to it. What programming problem is being solved here?
>
>The whole idea of public derivation is that a derived type can be
>used where ever a base type is expected. Why does the author of foo
>want to ensure that the actual object has, for example, no additional
>data, functionality, or instrumentation, when the author of Derived
>has no objections to the possibility?
>
>If for some reason you do care about the actual type of *object,
>wouldn't it be enough to use an RTTI expression in the function?

This could help for functions that take a Base[]:

class Base {
    public:
        void    (*func) ();
};

class Derived {
    public:
        long    dummy;
};

void    foo_safe (explicit Base[]);
void    foo_bad (Base[]);

void    test ()
{
    Base*     der = new Derived[10];

    foo_bad (der); // pass at compile time, then crash
    foo_safe (der);
// the compiler will tell you 'cannot convert from Base* to explicit Base*'
}

void    foo_bad (Base[] b)
{
    for (int i=0; i<10; i++)
        (b[i].func) (); // function call here to be sure that it crash ;->
}

void    foo_safe (explicit Base[] b) // do the same thing
{
    for (int i=0; i<10; i++)
        (b[i].func) ();
}

I know a could use a container, but the notion of array use sometimes useful for class too.

Well, this was not the point of my idea: I wanted to the compiler to know at compile time the 'real' type of the object, not:
- use RTTI (contrary of compile time !)
- not just to protect from error (see example above)
- 'create a type which cannot be derived from', as Steve Clamage say.
  (The class Derived can be derived from, since, it has a normal declaration.)

I wrote:
> object.VirtualFunc (); // nop (compiler does not generate code for this)

Since VirtualFunc is virtual, the compiler must generate code for it, even when object is a Base& and Base::VirtualFunc is defined as { } *except* if:
(a) the variable is passed by value
(b) you use explicit

(a) as obvious disadvantages in terms of speed for big classes, so the last solution is (b)...

Note: the rule for the qualifier are the *inverse* of the rules for cv (const/volatile):
~~~~~
T* -> const T*          const T* !=> T*
T* -> volatile T*       volatile T* !=> T*
but
explicit T* -> T*       T* !=> explicit T*

where -> means can be converted to and !=> means CAN'T be converted to.


>>4) Conversion of Type** to const Type**
>>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>>It's ok, this is an error; but why cannot Type** be converted to const Type* 
>>const* ?
>
>For the same reason: it could cause a violation of constness without
>a cast. The draft standard does allow Type** to be converted to
>"Type*const*", since that cannot cause any such violation.

I don't see how you could violate constness _without_ the cast; if you know, please tell me.


Valentin Bonnard
bonnardv@pratique.fr
---
[ 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 
]
Re: Some ideas about C++ and a question
#3654
Author: James Kanze US/ESC 60/3/141 #407...
Date: Wed, 13 Mar 1996 16:19
38 lines
2523 bytes
In article <v01530500ad6a43009478@[194.98.4.120]> bonnardv@pratique.fr
(Valentin Bonnard) writes:
|> clamage@Eng.Sun.COM (Steve Clamage) wrote:
|> >Valentin Bonnard <bonnardv@pratique.fr> writes:

|> >>4) Conversion of Type** to const Type**
|> >>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|> >
|> >>It's ok, this is an error; but why cannot Type** be converted to
|> >>const Type* const* ?

It can.  It was banned in the C standard, and the C++ committee only
changed this rule recently, so it is possible that many compilers
don't implement it yet.  (It was banned by mistake in the C standard;
the wording to forbid Type** -> Type const** was made too tight.)

|> >For the same reason: it could cause a violation of constness without
|> >a cast. The draft standard does allow Type** to be converted to
|> >"Type*const*", since that cannot cause any such violation.

|> I don't see how you could violate constness _without_ the cast; if you
|> know, please tell me.

I think Steve just misread your statement.  (I know I did the first
time through.)  Why you cannot convert Type** to Type const** is
almost a FAQ, and since since that was the title of point 4...

--
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.  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                             ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads