Topic: Template abs function???


Author: AllanW@my-dejanews.com
Date: 1998/06/04
Raw View
In article <6jeoku$ta0$1@nnrp1.dejanews.com>,
  jkanze@otelo.ibmmail.com wrote:
> In article <3559447F.D9AAC653@physik.tu-muenchen.de>,
>   Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> > What about the following program:
[example deleted]
>
> This program has no observable behavior, so all that is required
> is that the compiler generate a program without any observable
> behavior.  A good compiler for an Intel platform, for example,
> might generate:
>     main:
>         mov eax , 0
>         ret
> (For what it's worth, such compilers do exist, although perhaps not
> for C++.  I actually used one for C about 10 years ago.)



* * * Announcing:  E-MCC(tm) * * *
      The new C++ compiler coming soon from Ronko(tm)!

Ronko(tm), the same company that brought magic to your kitchen, with
    * Magic Shami
    * Ginsu Knives
    * Magic Mop
    * Cubic Egg Press
    * Magic Wok
now brings this same brand of magic to the world of compilers.  It slices,
it dices, and it has every feature you could ever want from an optimizing C++
compiler.  Ladies and gentlemen, Ronko(tm) is proud to announce that in late
spring of 1998, we will release the first of our soon-to-be-popular programmer
series:
    The Extremely-Magic C++ Compiler (E-MCC(tm) for short
with our exclusive, patented:
    Psychic Object-Oriented Optimization Procedure (POOOP(tm) for short).

What makes E-MCC(tm) so special?  Optimizations!

Any compiler can optimize this:
    for (int i=0; i<1000000; ++i)
        continue;
into the equivalent of this:
    ;

But only Ronko(tm)'s E-MCC(tm) with POOOP(tm) can optimize this:
    #include <iostream>
    class A { protected: int _a; A(int a) : _a(a) {} };
    class B { protected: int _b; B(int b) : _b(b) {} };
    class C : A, B { public: C(int a,int b):A(a),B(b){} void show(); };
    void C::show() { std::cout << _a << ' ' << _b << ' '; _a+=_b; _b+=_a; }
    int main() { C c(1,1); for (int i=0;i<10;++i)c.show(); return 0; }
into the equivalent of this:
    int main() {
        puts("1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 "
            "6765 ");
        return 0; }

Or optimize this:
    #include <iostream>
    #include <ctime>
    using namespace std;
    int main(int argc, char*argv[]) {
        int maxprime = 10;
        if (time(0)>maxprime) maxprime *= maxprime;
        for (int i=1; i<=maxprime; ++i) // Note error: i=1 instead of i=2
        {
            for (int j=2; j*j<i; ++j)
                if (0 == (i%j)) goto a;
            cout << ' ' << i;
    a:
        }
        return 0;
    }
into the equivalent of this:
    #include <stdio.h>
    int main() {
        // Note that primes begin with 2, not 1
        puts( time(0)>10
            ? " 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73"
              " 79 83 89 97"
            : " 2 3 5 7");
        return 0;
    }

Or even optimize this program (which computes 0+1+2+...+99 the hard way):
    #include <iostream>
    #include <iomanip>
    using namespace std;
    enum OPCODE { LOAD, STO=1000, ADD=2000, SUB=3000, MUL=4000,
        DIV=5000, MOD=6000, SET=9000, JMP=10000, JMPN=11000,
        JMPP=12000, JMPZ=13000, HALT=999998, DUMP=999999 };
    long pc,accum; long m[1000]={SET, STO+999, STO+998, LOAD+998,
        ADD+999, STO+998, SET+1, ADD+999, STO+999, SET+100, SUB+999,
        JMPP+3, LOAD+998, HALT };
    void load(){accum=m[m[pc]%1000];} void sto(){m[m[pc]%1000]=accum;}
    void add(){accum+=m[m[pc]%1000];} void sub(){accum-=m[m[pc]%1000];}
    void mul(){accum*=m[m[pc]%1000];} void div(){accum/=m[m[pc]%1000];}
    void mod(){accum%=m[m[pc]%1000];} void set(){accum=m[pc]%1000;}
    void jmp(){pc=(m[pc]%1000)-1;}    void jmpn(){if(accum<0)jmp();}
    void jmpp(){if(accum>0)jmp();}    void jmpz(){if(!accum)jmp();}
    void halt(){cout << "Normal end, PC=" << pc << ", Accum="
        << accum << endl; exit(0); }
    void dump() { cout << "Abnormal end, PC="<<pc<<", Accum="
        <<accum<<'\n'; for(int s=0,l=0;s||l<1000;l+=5) {
            if (l&&l<1000&&m[l]==m[l-5]&&m[l+1]==m[l-4]&&
                m[l+2]==m[l-3]&&m[l+3]==m[l-2]&&m[l+4]==m[l-1])
                { s+=5; continue; }
            if (s) { cout<<"  ("<<(l-s)<<" - "<<(l-1)
                <<") : Same as "<<(l-s-5)<<" - "<<(l-s-1)<<'\n';
                s=0; if (l>=1000) break; }
            cout << setw(3) << l << ": ";
            for (int i=0;i<5;++i)cout<<' '<<setw(8)<<m[l+i]; cout<<endl;
        } exit(1); }
    struct { long low; long hi; void(*fn)(void); } vector[] = {
        {LOAD,LOAD+999,load}, {STO, STO +999,sto }, {ADD, ADD +999,add },
        {SUB, SUB +999,sub }, {MUL, MUL +999,mul }, {DIV, DIV +999,div },
        {MOD, MOD +999,mod }, {SET, SET +999,set }, {JMP, JMP +999,jmp },
        {JMPN,JMPN+999,jmpn}, {JMPP,JMPP+999,jmpp}, {JMPZ,JMPZ+999,jmpz},
        {HALT,HALT,    halt}, {0,   0,       dump} };
    int main() {
        for (pc=0;;++pc){int i;
            for (i=0;i<sizeof(vector)/sizeof(vector[0])-1;++i)
                if (m[pc]>=vector[i].low && m[pc]<=vector[i].hi) break;
            vector[i].fn(); } }
into the equivalent of this:
    int main() {
        puts("Normal program termination.  PC=13, Accum=4950\n");
        return 0; }

"How does it work?" you may ask.  Seriously, we can't reveal all the secrets
behind our patented technology Psychic Object-Oriented Optimization Procedure
(POOOP(tm) for short). But we can tell you that it works with a combination
of techniques:
    * First, the E-MCC(tm) compiler analyzes the program, going beyond what
the
        programmer has actually written, to determine the meaning of the
        program, optionally fixing certain errors as it goes.
    * Then, POOOP(tm) technology begins to evaluate what would happen if the
        program was executing now.  So long as it is possible to determine the
        results ahead of time, POOOP(tm) continues to analyze.  This phase
        doesn't end until the program's "observable behavior" depends on
        some data not available at compile time (or until the program ends).
    * Optionally, the program then uses special POOOP(tm) technology to
        psychically read the mind of the programmer, and compare it to the
        results so far.  A special merge phase changes the program's meaning
        to match what the programmer actually meant.  Note: This removes all
        remaining bugs from the program.  In fact, since some bugs are of the
        "I forgot to write that function" variety, this phase can actually
        finish writing the program for you, along with required tasks such as
        testing, debugging, and documentation.
    * Finally, the results so far are re-optimized to produce the same
        observable results.

Check out the E-MCC(tm) web site at
    http://www.psychic.ronko.com/E-MCC/index.html
for some real-life examples you can download, including:

*** A 230,000-line retail Accounts Receivable/Inventory system, altered
        to accept sales from a batch file (to enable our test suite),
        plus a test suite of 150,000 sales, including 2,000 out-of-stock
        and 2,000 from customers marked "bad credit-cash only."
    Originally 2.9Meg, and required 49:33 to execute our test suite on
        our low-end test computer (*).
    When compiled by Ronko's amazing E-MCC(tm), the program shrank to
        3,420 bytes, and our test computer (*) ran the test suite in just
        4 seconds (it might have been 3.5 seconds, but our stopwatch
        finger isn't that fast!)  The compiler also found and fixed 12
        errors, including 3 logic errors we didn't know about (but the
        compiler was right!), 3 logic errors we did know about, and 6
        cases of poor programmer style (improper indentaion, misleading
        variable names, missing or obscure comments, etc.)
    In real life, the Accounts Receivable program is now being used in the
        field, by some of the happiest customers on the planet.  One firm
        reported that after their shop closed at 6:00 PM, they used to have
        to wait until 8:00 PM for their daily reports to finish.  But that's
        a thing of the past.  Now, they can run their daily reports at
        lunchtime, even though the daily sales haven't all been entered yet.
        "It's amazing that it can do this," said the owner of the company,
        who used to be an accountant.  "I would have sworn it was impossible
        to print the output before the input was entered, and yet her it is
        in black and white.  And the numbers are always exactly right!"
    Seriously, that same company will soon be testing the Accounts Payable
        and Payroll modules as soon as the current compile finishes, which
        should be sometime in the first quarter of 1999.

    (*)Our test machine was rather "low end", in order to dramatize the
        tremendous advantages of using Ronko's amazing E-MCC(tm).  It was a
        386SX/20 with 2Meg of RAM, a CGA monitor, 3.5" 1.44Meg Floppy, and a
        120Meg IDE disk drive.  There was no CD-reader or mouse.

But that's not all!  If you buy E-MCC(tm) Gold Edition(tm), you get all of
the features from E-MCC(tm) Standard Edition(tm), plus more:
    * Automatic Documentation.  E-MCC(tm) makes programmer documentation
        obsolete; once you know what you want to do, E-MCC(tm) has already
        done it.  But what about the end-user documentation?  E-MCC(tm) Gold
        Edition(tm) will automatically generate clear, simple documentation
        that any user can understand, in your choice of (one or more of)
        156 languages.
    * Telephone support.  Even with the best user manuals, some customers
        simply need "hand holding." But don't worry -- just let E-MCC(tm)
        Gold Edition(tm) answer the phone for you!  It will analyze your
        program to answer any natural-language question (in the user's choice
        of 183 languages -- including all 156 languages with user manuals,
        plus 27 languages that have no alphabet or writing!  E-MCC(tm) will
        explain things slowly and clearly, and with infinite patience.
        In preliminary testing, we've satisfied 100% of our army of over 2,000
        beta test callers simply by explaining how they should have used the
        program.  But in the rare case that a problem does turn out to be a
        bug(*), E-MCC(tm) will locate an existing patch, or (if neccesary)
        create one on it's own, and make it available to the customer for
        download via Internet or modem, or will generate the floppy disk image
        and automatically print out the envelope for postal mail!
        (Suitable computer hardware -- such as a telephone voice module -- is
        required for full operation of this feature.)
        (*) So far, this has been demonstrated with brute-force attacks only.
        This is because E-MCC(tm) automatically removes the bugs during the
        compile, so calls of this nature should be impossible.

Frequently asked questions:
Q1: Fixing errors can cause a change in observable behavior.  For instance,
    say that we have a function which will eventually display the customer's
    balance, but currently is just a stub function displaying the number 0.
    If E-MCC(tm) writes this function for the programmer, the observable
    behavior will change from displaying 0 to displaying the correct number!
    Does that mean that E-MCC(tm) isn't ANSI-complaint?
A1: Not at all, ha ha!  Seriously, it is permissible for an ANSI-compliant
    compiler to require certain compiler switches or options in order to
    provide full ANSI compliance.  In the case of E-MCC(tm), you can turn off
    the POOOP(tm) technology to achieve this.  The program will still achieve
    remarkably high optimization rates, but will not attempt to read your mind
    or perform any other optimizations that affect observable behavior.
Q2: What if the compiler "fixes" something that I didn't want it to?
A2: Relax, ha ha!  Seriously, that can't happen, not even with POOOP(tm)
    technology enabled.  The compiler always determines what you *really*
    meant for the program to do before it makes any changes of this sort.  In
    our prime number example above, the programmer didn't want to start with
    number 1 -- if she did, the compiler would have left it alone!
Q3: Can anybody use E-MCC(tm)?
A3: No, E-MCC(tm) is reserved for our registered users only, ha, ha!
    Seriously, anybody can use it with POOOP(tm) technology turned off.  Using
    the POOOP(tm) interface requires each programmer to have at least a vague
    idea about what the program should do; the better the programmer
    understands this, the better the results.  Therefore, the compiler works
    best for "C++ Language Lawyers," but we've also had some success with
    regular attorneys-at-law, and with programmers that use C, ADA, and any
    assembly language.  You may have heard of our near-fatality with a Visual
    Basic programmer.  Rest assured; we've added safeguards to prevent this
    from ever happening again.  The programmer is doing quite well in one of
    our state mental hospitals, thanks to the funds we give to our new
    business partner, who also happens to be the former VB programmer's wife.
Q4: Some of your compiles take 6 to 8 months or even longer.  Isn't that a
    bit excessive?
A4: Maybe, ha ha!  Seriously, remember that the usual Edit-Compile-Link-Test-
    Debug cycle is considerably shorter when you use E-MCC(tm).  In fact, once
    you've compiled your program with E-MCC(tm) with POOOP(tm) technology
    enabled, you may never have to make another change!  And if you do, all
    you have to do is think about what you really want -- there's no
    "Analysis" or "Design" or "Debugging" required as such.  So look at it
    this way: if you could cut a 3-year development project into ONE compile,
    which happened to take 6 months to finish, wouldn't you want to do that?
Q5: I'm still worried.  Is there any way to speed up compiles?
A5: Who know, ha ha?!?  Seriously, we think so, but we can't officially
    promise it (yet).  Remember that as we write this, E-MCC(tm) with
POOOP(tm)
    technology is still not a released product.  We think that compiles will
    go much faster once we've used E-MCC(tm)'s POOOP(tm) technology to compile
    E-MCC(tm) itself.  This should also complete all of the additional
features
    we have had planned, as the POOOP(tm) technology should be able to figure
    out what we planned to do, and add those features for us automatically!
    That newest compile of E-MCC(tm) has been going on for some time now; in
    fact, it was almost finished last April, but a power failure stopped it
    mere weeks before it would have finished!  (Arrgh!)  Since then, we have
    installed a UPS (Uninterruptable Power Supply), and we recommend that all
    of our customers do so as well.  Meanwhile, the current effort is expected
    to end in early Spring, which is why we plan to start retail sales of
    E-MCC(tm) in late Spring.  We should also have user documentation and
    telephone support ready at that time.
Q6: Once I have an idea for a program, and my copy of E-MCC(tm), what else do
    I need for a successful career?
A6: Obviously, you're going to need a computer, ha ha!  Seriously, the
    computer should have a good printer and voice communication hardware as
    well, but both of these things are optional.  You need some way to sell
    your product, since nobody will buy it if nobody has heard of it; a sales
    force is strongly recommended, but you can also do this yourself.
    Publicity will help a great deal with this. After that, you will probably
    need a checking account with no restrictions on maximum balance.  For
    frequent compiles, a large bottle of aspirin is also a good idea.
Q7: So, how do I get my copy?
A7: Glad you asked, ha ha!  Seriously, starting in late spring 1998,
    E-MCC(tm) Standard Edition(tm) and E-MCC(tm) Gold Edition(tm)
    will be in retail distribution, and also available via mail order and at
    larger computer software distributors nationwide.  But you don't have to
    wait!  Simply fill out and mail the coupon below, along with your check
    or money order.

    +-------------------------------------------------------------------+
    |                                                                   |
    |                                                                   |
    |                                  Date Mailed: __________________  |
    |  Mail To: Ronko(tm)                                               |
    |           Amazing E-MCC(tm) Compiler DiscountOffer                |
    |           Attn: Department Usenet.comp.std.c++                    |
    |           1 Helluva Drive                                         |
    |           Beverly Hills, NY 99999 USA                             |
    |                                                                   |
    |  Please print carefully, this will be used as your shipping label |
    |                                                                   |
    |  From:                                                            |
    |       (company name)____________________________________________  |
    |                                                                   |
    |       (your name)_______________________________________________  |
    |                                                                   |
    |       (your title)______________________________________________  |
    |                                                                   |
    |       (your address)____________________________________________  |
    |                                                                   |
    |       __________________________________________________________  |
    |                                                                   |
    |       (your city)_______________________________________________  |
    |                                                                   |
    |       (your state or province) _________________________________  |
    |                                                                   |
    |       (your postal or ZIP code)_________________________________  |
    |                                                                   |
    |       (your country)____________________________________________  |
    |                                                                   |
    |  Dear Ronko:                                                      |
    |  I've heard enough!  Sign me up right now for                     |
    |      [_] E-MCC(tm) Standard Edition(tm).  The suggested retail    |
    |          price is $45,000,000,000.00.  But with this special      |
    |          offer, I will buy it for just $40,499,999,999.96.        |
    |          That's over 10% off -- a savings of over $4 billion!     |
    |          Here's my check or money order for at least 25%          |
    |          (that's $10,249,999,999.99) in United States funds       |
    |          only.  Bill me for the rest (if any).                    |
    |                                                                   |
    |      [_] E-MCC(tm) Gold Edition(tm).  The suggested retail price  |
    |          is $47,800,000,000.00.  But with this special offer, I   |
    |          will buy it for just $42,999,999,999.96.  That's over    |
    |          10% off -- a savings of over $4.8 billion!               |
    |          Here's my check or money order for at least 25%          |
    |          (that's $10,749,999,999.99) in United States funds       |
    |          only.  Bill me for the rest (if any).                    |
    |                                                                   |
    |  Seriously, I promise to wait 6-8 weeks for you to acknowledge    |
    |       my order.                                                   |
    |                                                                   |
    |                                                                   |
    |  Signature: ____________________________________________________  |
    |                                                                   |
    |                                                                   |
    +-------------------------------------------------------------------+

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

[ moderator's note: followup postings will be rejected. :-) -sdc ]



[ comp.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: kanze@gabi-soft.fr (J. Kanze)
Date: 1998/05/22
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

|>  Matt Austern wrote:
|>  >
|>  > > But unless explicitly stated otherwise *the standard does NOT
|>  > > allow the compiler to change the semantics of a program, even
|>  > > sligtly*.
|>  >
|>  > But with one big exception: the compiler may change the semantics
|>  > however it likes, if there's no way to tell the difference.  (The "as
|>  > if" rule.)
|>
|>  If there's no way to tell the difference, the semantics of the
|>  program has not been changed...

It depends on how you define semantics.  The standard defines
"observable behavior", and the only requirement is that this doesn't
change.  Observable behavior is very restricted.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1998/05/22
Raw View
stevenp@bnr.co.uk (Steven Perryman) writes:

|>  In article <xajzpgjnseh.fsf@korrigan.inria.fr> Gabriel Dos_Reis <gdosreis@sophia.inria.fr> writes:
|>
|>  >Formally an implementation is free to pass en argument by value to a
|>  >function declared to take the argument by reference (note that
|>  >refrence in a foreign concept to C) provided the program output
|>  >doesn't change, except that in C++ it does make a big difference
|>  >(semantically speaking and the semantic is part of the observable
|>  >behavior) to pass by a reference or by value, as a refrence is just
|>  >another the name of an object.
|>
|>  Are there any compilers that actually do the above ??
|>  I tried bog-std g++ some time ago, and for basic types like int it leaves
|>  const& parameters as is, rather than going with const int etc.

Typically, most compilers will not be able to make the change unless
they can see the body of the called function.  In the case of g++, it
can only see the body if the function is declared inline -- if g++
actually does inline the function, I'm pretty sure that it doesn't
generate a spurious reference (but what does call-by-reference
vs. call-by-value mean if there is no call).

G++ is not particularly state of the art, except perhaps when it comes
to portability.  Other compilers can and do defer inlining until after
link, use profiling output to determine likely candidates, etc.  Such
compilers could easily do said optimization.  In practice, I doubt they
will bother, since if the function is small enough, and called often
enough, for it to make a difference, they would probably inline it
anyway.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/20
Raw View
Christopher Eltschka wrote:
>
> jkanze@otelo.ibmmail.com wrote:
...
> > The notion of observable behavior is very limited; basically, it
> > only concerns what would normally result in system calls (IO, principally)
> > and volitile variables.  An implementation is free to pass an
> > argument by value to a function declared to take the argument by
> > reference, provided the program output doesn't change.
>
> But this implies that the compiler can prove that the program output
> doesn't change. Can you say "halting problem"?

The fact that you can't decide in general whether an arbitrary program
will halt, doesn't mean there aren't specific programs where you can.
When the standard contains a statement which says "...an implementation
may [some action] if it can be proved that [some condition] ...", it
doesn't mean that an implmentation has to decide whether the condition
is true whenever it runs into code for which the statment applies. It
merely means that if the implementation runs into code for which the
truth of the condition can be proven, the implementation is free to take
the corresponding action.


[ comp.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: Gabriel Dos Reis <dosreis@DPTMaths.ens-cachan.fr>
Date: 1998/05/21
Raw View
>>>>> =ABJames=BB, James Kuyper <kuyper@wizard.net> wrote:

James> Christopher Eltschka wrote:
>>=20
>> jkanze@otelo.ibmmail.com wrote:
James> ...
>> > The notion of observable behavior is very limited; basically, it
>> > only concerns what would normally result in system calls (IO, princi=
pally)
>> > and volitile variables.  An implementation is free to pass an
>> > argument by value to a function declared to take the argument by
>> > reference, provided the program output doesn't change.
>>=20
>> But this implies that the compiler can prove that the program output
>> doesn't change. Can you say "halting problem"?

James> The fact that you can't decide in general whether an arbitrary pro=
gram
James> will halt, doesn't mean there aren't specific programs where you c=
an.
James> When the standard contains a statement which says "...an implement=
ation
James> may [some action] if it can be proved that [some condition] ...", =
it
James> doesn't mean that an implmentation has to decide whether the condi=
tion
James> is true whenever it runs into code for which the statment applies.=
 It
James> merely means that if the implementation runs into code for which t=
he
James> truth of the condition can be proven, the implementation is free t=
o take
James> the corresponding action.

Alas, there is still a *big* gap between what an implementation _may_ do
and what it does (or can do) _in practice_. This makes a big
difference in real world.

-- Gaby
---
[ comp.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: stevenp@bnr.co.uk (Steven Perryman)
Date: 1998/05/18
Raw View
In article <xajzpgjnseh.fsf@korrigan.inria.fr> Gabriel Dos_Reis <gdosreis@sophia.inria.fr> writes:

>Formally an implementation is free to pass en argument by value to a
>function declared to take the argument by reference (note that
>refrence in a foreign concept to C) provided the program output
>doesn't change, except that in C++ it does make a big difference
>(semantically speaking and the semantic is part of the observable
>behavior) to pass by a reference or by value, as a refrence is just
>another the name of an object.

Are there any compilers that actually do the above ??
I tried bog-std g++ some time ago, and for basic types like int it leaves
const& parameters as is, rather than going with const int etc.


Regards,
Steven Perryman
stevenp@nortel.co.uk


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matt Austern <austern@sgi.com>
Date: 1998/05/18
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

> > The notion of observable behavior is very limited; basically, it
> > only concerns what would normally result in system calls (IO, principally)
> > and volitile variables.  An implementation is free to pass an
> > argument by value to a function declared to take the argument by
> > reference, provided the program output doesn't change.
>
> But this implies that the compiler can prove that the program output
> doesn't change. Can you say "halting problem"?

It's easy to prove that this is an unsolvable problem in general.
However, and it's a big however, it's a perfectly solvable problem in
lots of special cases.  (Including some "special cases" that make up
the vast majority of real programs.)

That's what compilers are all about: proving that a certain
optimization can safely be applied to the program at hand.  It doesn't
matter that you can't do the proof in general, provided that the
compiler can recognize the special cases where it does know how to do
the proof.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/19
Raw View
Gabriel Dos_Reis wrote:
...
> another the name of an object. How can you in general tell if there
> will be no difference in the observable behavior if you pass by value
> instead of refrence ? If the function has a side effect (or calls a

You can't tell in general; that's the whole point. The compiler can tell
in specific cases (most often when the function being called is declared
'inline').
---
[ comp.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: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1998/05/11
Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:

> Ross Smith wrote:
> >=20
> > Your library is faulty. According to the draft standard, abs() is
> > supposed to be overloaded for int, long, float, double, and long
> > double.
>=20
> I only see it for complex<T>, valarray<T>, float, double and long
> double. I don't see it for int or long.

You're right.=20

>=20
> It would seem to make sense for abs(int) to return unsigned int, and
> abs(long) to return unsigned long, thus causing them to work correctly
> on two's complement machines when given the maximum negative number. An=
y
> comments?
>=20

100% agreed. BTW, norm(const complex<T>&) *should* return the unsigned=20
type analogue of T, when possible. That is=20

 norm(const complex<int>&)=20

sould return an unsigned int. And yes, complex<int> gets in use.

A question: why does

template<class T> complex<T> operator+(const complex<T>&, const T&);

take a const _reference_ as a second argument and rather than the most
efficient of { T, const T& } ? It's less efficeint to pass a float by con=
st
reference rather than value IMHO.

--=20
Gabriel Dos Reis                   |  Centre de Math=E9matiques et de Leu=
rs
dosreis@cmla.ens-cachan.fr         |             Applications
Fax : (33) 01 47 40 21 69          |   ENS de Cachan -- CNRS (URA 1611)
               61, Avenue du Pdt Wilson, 94235 Cachan - Cedex
---
[ comp.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: Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk>
Date: 1998/05/11
Raw View
jkanze@otelo.ibmmail.com wrote:
>
> In article <355054FB.3D8D@cs.bham.ac.uk>#1/1,
>   Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk> wrote:
> >
> > Does anyone know why there isn't there a template version of the `abs'
> > function that works for all numbers, and not just ints? The stdlib one
> > just works for integers - which is a tad limited.
>
> I think you just answered your own question: the function is already
> defined in the standard library -- it could be overloaded, but a
> template would pose incompatibility problems with C.

True. Putting it inside the std:: namespace would fix this. However,
namespaces aren't implemented in g++. I'm amazed such a tiny and useful
function hasn't found its way into the standard libraries yet.


Stuart
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/11
Raw View
Stuart I Reynolds wrote:
>
> Does anyone know why there isn't there a template version of the `abs'
> function that works for all numbers, and not just ints? The stdlib one
> just works for integers - which is a tad limited.
>
> e.g.
>
> template <class T>
> T abs(const T& n)   //name conflicts with one on stdlib
> {
>   return  (n>T(0)) ? n : -n;
>
> }

It would be interesting to try this template on a complex number ;-)
AFAIK, the standard overloads abs for the float types and complex types
as well.

BTW, from g++-2.8.1's cmath header:

...
#include <math.h>
...
inline float  abs (float  x) { return fabs (x); }
#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
inline double abs (double x) { return fabs (x); }
#endif
...
inline long double abs (long double x) { return fabs (x); }

And in its std/complext.h header (included by complex header):

...
template <class _FLT> inline _FLT
abs (const complex<_FLT>& x) __attribute__ ((const));
...


[ comp.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: Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk>
Date: 1998/05/11
Raw View
Daniel Parker wrote:
>
> Stuart I Reynolds wrote in message <355054FB.3D8D@cs.bham.ac.uk>...
> >Does anyone know why there isn't there a template version of the `abs'
> >function that works for all numbers, and not just ints? The stdlib one
> >just works for integers - which is a tad limited.
> >
> >e.g.
> >
> >template <class T>
> >T abs(const T& n)   //name conflicts with one on stdlib
>
> So put it in a different namespace, that's what namespaces are for.


I tried that. g++ 2.8 says these aren't implemented yet when I try to
use them. Bah :(


Stuart

--
+-+- Office: G8, School of Computer Science, University of Birmingham,
| |          Edgbaston, Birmingham, B15 2TT. UK.
| +- tel: +44-121-414-7969
+--- mailto:sir@cs.bham.ac.uk
+--- http://www.cs.bham.ac.uk/~sir/


[ comp.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: A.Stokes@globalcomm.co.uk
Date: 1998/05/12
Raw View
In article <xajra207hmt.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
> 100% agreed. BTW, norm(const complex<T>&) *should* return the unsigned=20
> type analogue of T, when possible. That is=20
>
>  norm(const complex<int>&)=20
>
> sould return an unsigned int. And yes, complex<int> gets in use.

Really? The FDIS says "The effect of instantiating the template complex for
any type other than float, double or long double is
unspecified."

>
> A question: why does
>
> template<class T> complex<T> operator+(const complex<T>&, const T&);
>
> take a const _reference_ as a second argument and rather than the most
> efficient of { T, const T& } ? It's less efficeint to pass a float by con=
> st
> reference rather than value IMHO.

I don't think anything in the standard prevents a compiler from passing a
const reference parameter by value (it can make a copy and bind the reference
to that, and then eliminate the reference), and I would hope a good one would
do so for small types.

- Alan

-----== 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: jkanze@otelo.ibmmail.com
Date: 1998/05/12
Raw View
In article <xajra207hmt.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
>
> > It would seem to make sense for abs(int) to return unsigned int, and
> > abs(long) to return unsigned long, thus causing them to work correctly
> > on two's complement machines when given the maximum negative number. An=
> y
> > comments?
> >=20
>
> 100% agreed.

I'm not sure.  The change of type can lead to some surprising effects,
since any arithmetic involving an unsigned is itself unsigned.  Consider
an expression like -abs( i ); most people (myself included) would expect
this to return a negative value (or zero).

> A question: why does
>
> template<class T> complex<T> operator+(const complex<T>&, const T&);
>
> take a const _reference_ as a second argument and rather than the most
> efficient of { T, const T& } ? It's less efficeint to pass a float by con=
> st
> reference rather than value IMHO.

By the general rule that unknown types (in templates) are always passed
by const reference, on the grounds that the cost of passing the built-in
types by reference is not that high, but the cost of passing a class type
by value can be.

In this case, of course, I expect that most applications will never
instantiate complex for anything other than float or double.  A good
implementation will provide a specialization for these types which
will pass by value, or more likely, the functions will be inline, and
it will count on the compiler doing the necessary optimization.

--
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/   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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/05/12
Raw View
jkanze@otelo.ibmmail.com wrote:
>
> In article <xajra207hmt.fsf@korrigan.inria.fr>,
>   Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:

> > A question: why does
> >
> > template<class T> complex<T> operator+(const complex<T>&, const T&);
> >
> > take a const _reference_ as a second argument and rather than the most
> > efficient of { T, const T& } ? It's less efficeint to pass a float by con=
> > st
> > reference rather than value IMHO.
>
> By the general rule that unknown types (in templates) are always passed
> by const reference, on the grounds that the cost of passing the built-in
> types by reference is not that high, but the cost of passing a class type
> by value can be.

The best solution is IMO to add a trait for that. It would indicate
if the object should be passed by reference or by value; this has
already been discussed in the newsgroups.

> In this case, of course, I expect that most applications will never
> instantiate complex for anything other than float or double.  A good
> implementation will provide a specialization for these types which
> will pass by value,

Sorry, no, here is a possible testsuite for this:

typedef std::complex<float> cft;

// negative test (required to fail)
cft (*f) (const float&, const sft&) = &std::operator+;

// possitive test (required to pass)
cft (*f) (float, const sft&) = &std::operator+;

> or more likely, the functions will be inline, and
> it will count on the compiler doing the necessary optimization.

Yes

--

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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/05/12
Raw View
A.Stokes@globalcomm.co.uk wrote:

> I don't think anything in the standard prevents a compiler from passing a
> const reference parameter by value

References are references - that's all. Nothing in the standard
allow any perversion of their semantics.

So pass by reference should work as pass by reference. For
the std library, it won't make any differences as long as
taking pointers to functions works, so in this particular
case, with some magic, the optimisation you describe is
possible.

But unless explicitly stated otherwise *the standard does NOT
allow the compiler to change the semantics of a program, even
sligtly*.

--

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: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1998/05/12
Raw View
jkanze@otelo.ibmmail.com writes:

>
> I'm not sure.  The change of type can lead to some surprising effects,
> since any arithmetic involving an unsigned is itself unsigned.  Consider
> an expression like -abs( i ); most people (myself included) would expect
> this to return a negative value (or zero).

when you write something like this you have to think about it at leats
twice :-)

>
> > A question: why does
> >
> > template<class T> complex<T> operator+(const complex<T>&, const T&);
> >
> > take a const _reference_ as a second argument and rather than the most
> > efficient of { T, const T& } ? It's less efficeint to pass a float by con=
> > st
> > reference rather than value IMHO.
>
> By the general rule that unknown types (in templates) are always passed
> by const reference, on the grounds that the cost of passing the built-in
> types by reference is not that high, but the cost of passing a class type
> by value can be.
>

Why not use traits (from Nathan) to specify this ?


// this is for general unknown type.
template<typename T> struct most_efficient {
 typedef const T& type;
 //...
};

template<> struct most_efficient<int> {
 typedef int type;
 //...
};

  norm(typename most_efficient<T>::type );

> In this case, of course, I expect that most applications will never
> instantiate complex for anything other than float or double.  A good
> implementation will provide a specialization for these types which
> will pass by value, or more likely, the functions will be inline, and
> it will count on the compiler doing the necessary optimization.

since the Standard does not mandate this, it sounds like the user have
to recode the Standard to make sure his application wil be
portable. Not good.


-- Gaby
---
[ comp.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: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1998/05/12
Raw View
A.Stokes@globalcomm.co.uk writes:

> In article <xajra207hmt.fsf@korrigan.inria.fr>,
>   Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
> > 100% agreed. BTW, norm(const complex<T>&) *should* return the unsigned
> > type analogue of T, when possible. That is
> >
> >  norm(const complex<int>&)
> >
> > sould return an unsigned int. And yes, complex<int> gets in use.
>
> Really? The FDIS says "The effect of instantiating the template complex for
> any type other than float, double or long double is
> unspecified."
>

Yes. But this does not mean complex<int> *shall* not be intantiated. I
can understand why instantiating complex for bool is meaningless. But
does it apply for an int ? What I am asking for (in my initial post) is
something like

template<typename T, typename ReturnType=T>
 ReturnType norm(const comlex<T>&);

were one could specify the desired return type.

> >
> > A question: why does
> >
> > template<class T> complex<T> operator+(const complex<T>&, const T&);
> >
> > take a const _reference_ as a second argument and rather than the most
> > efficient of { T, const T& } ? It's less efficeint to pass a float by const
> > reference rather than value IMHO.
>
> I don't think anything in the standard prevents a compiler from passing a
> const reference parameter by value (it can make a copy and bind the reference
> to that, and then eliminate the reference), and I would hope a good one would
> do so for small types.


Hem. Since the Standard does not mandate an implementation to
specialize complex for int , long int, end users have no portable
way apart intanting them. They have to be optimistic and rely on a an
speculative optimiser.

--
Gabriel Dos Reis                   |  Centre de Math=E9matiques et de Leurs
dosreis@cmla.ens-cachan.fr         |             Applications
Fax : (33) 01 47 40 21 69          |   ENS de Cachan -- CNRS (URA 1611)
               61, Avenue du Pdt Wilson, 94235 Cachan - Cedex


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matt Austern <austern@sgi.com>
Date: 1998/05/12
Raw View

> But unless explicitly stated otherwise *the standard does NOT
> allow the compiler to change the semantics of a program, even
> sligtly*.

But with one big exception: the compiler may change the semantics
however it likes, if there's no way to tell the difference.  (The "as
if" rule.)


[ comp.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: "Cathy James" <Cathy.James.cajames@nt.com>
Date: 1998/05/13
Raw View
>> I don't think anything in the standard prevents a compiler from passing a
>> const reference parameter by value

>But unless explicitly stated otherwise *the standard does NOT
>allow the compiler to change the semantics of a program, even
>slightly*.

 In any case, there's definitely a difference in behavior.
A const reference could use an explicit cast to remove the const and modify
the original variable.  If passed by value, this wouldn't be possible,
ergo, you're not compliant.

-----------------------------------------------------------
| Cathy James <cajames@alumni.princeton.edu> PPSEL, N5WVR |
|                                                         |
|                                                         |
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Pete Becker <petebecker@acm.org>
Date: 1998/05/13
Raw View
Valentin Bonnard wrote:
>
> A.Stokes@globalcomm.co.uk wrote:
>
> > I don't think anything in the standard prevents a compiler from passing a
> > const reference parameter by value
>
> References are references - that's all. Nothing in the standard
> allow any perversion of their semantics.

No, but the "as if" rule permits the suggested optimization for types
without constructors or destructors.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/13
Raw View
<A.Stokes@globalcomm.co.uk> wrote:
>In article <xajra207hmt.fsf@korrigan.inria.fr>,
>  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
>> 100% agreed. BTW, norm(const complex<T>&) *should* return the unsigned=20
>> type analogue of T, when possible. That is=20
>>
>>  norm(const complex<int>&)=20
>>
>> sould return an unsigned int. And yes, complex<int> gets in use.
>
>Really? The FDIS says "The effect of instantiating the template complex for
>any type other than float, double or long double is
>unspecified."

Especially in implementations for embedded platforms, vendors are
likely to define semantics for complex<T> for T int, unsigned, short,
etc., for at least many of the functions.  Some vendors (e.g.) mightn't
provide transcendentals for these cases.

>> A question: why does
>>
>> template<class T> complex<T> operator+(const complex<T>&, const T&);
>>
>> take a const _reference_ as a second argument and rather than the most
>> efficient of { T, const T& } ? It's less efficeint to pass a float by con=
>> st
>> reference rather than value IMHO.
>
>I don't think anything in the standard prevents a compiler from passing a
>const reference parameter by value (it can make a copy and bind the reference
>to that, and then eliminate the reference), and I would hope a good one would
>do so for small types.

Since these are generally small inline functions, the compiler
has great latitude to avoid "passing" the arguments at all.

--
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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/13
Raw View
A.Stokes@globalcomm.co.uk wrote:
>
> In article <xajra207hmt.fsf@korrigan.inria.fr>,
>   Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
> > 100% agreed. BTW, norm(const complex<T>&) *should* return the unsigned=20
> > type analogue of T, when possible. That is=20
> >
> >       norm(const complex<int>&)=20
> >
> > sould return an unsigned int. And yes, complex<int> gets in use.
>
> Really? The FDIS says "The effect of instantiating the template complex for
> any type other than float, double or long double is
> unspecified."
>
> >
> > A question: why does
> >
> > template<class T> complex<T> operator+(const complex<T>&, const T&);
> >
> > take a const _reference_ as a second argument and rather than the most
> > efficient of { T, const T& } ? It's less efficeint to pass a float by con=
> > st
> > reference rather than value IMHO.
>
> I don't think anything in the standard prevents a compiler from passing a
> const reference parameter by value (it can make a copy and bind the reference
> to that, and then eliminate the reference), and I would hope a good one would
> do so for small types.

What about the following program:

// main.cc

int i;

void f(const int&);

int main()
{
  i=1;
  f(i);
  assert(i==2);
}

// f.cc

void f(const int& i)
{
  const_cast<int&>(i)=2;
}

According to the standard, this program must work (the assertion may
not fail: changing the reference obtained via with const_cast is well
defined since the object itself is not const). However, if the pass by
const reference were replaced by pass per value, it would not work.
(Personally, I'd prefer that changing a value obtained by const_cast
would be undefined in any case, as now when we have mutable, const_cast
is only used for interfaces which are not const_correct, and in this
case changing the value would be the wrong thing anyway; implementations
which don't support mutable are free to make additional guarantees to
define this undefined behaviour [and from the standard point of view,
those are non-conforming anyway, so any behaviour of them is undefined
since the standard does not define behaviour of non-conforming
implementations...])
---
[ comp.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: A.Stokes@globalcomm.co.uk
Date: 1998/05/13
Raw View
In article <3558935A.263A@pratique.fr>,
  Valentin Bonnard <bonnardv@pratique.fr> wrote:
>
> A.Stokes@globalcomm.co.uk wrote:
>
> > I don't think anything in the standard prevents a compiler from passing a
> > const reference parameter by value
>
> References are references - that's all. Nothing in the standard
> allow any perversion of their semantics.

I wasn't suggesting a perversion, I was suggesting an optimisation, i.e. a
way of providing the same semantics more efficiently.

> ...
> But unless explicitly stated otherwise *the standard does NOT
> allow the compiler to change the semantics of a program, even
> sligtly*.

Of course - but I was suggesting that the semantics were equivalent from what
the standard says. But as others have pointed out I was wrong since the
called function can cast away the const and modify the underlying value. (I'd
misremembered and thought that the compiler was always free to make a copy
when binding a const reference.)

If the compiler has enough information it can still perform the optimisation
- e.g. if it knows that the called function doesn't do the const_cast, or in
the cases where it is explicitly permitted to make a copy. But there aren't
yet many compilers smart enough to do this sort of thing across different
compilation units, except for inline functions.

-----== 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/13
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>A.Stokes@globalcomm.co.uk wrote:
>>   Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
>> >
>> > A question: why does
>> >
>> > template<class T> complex<T> operator+(const complex<T>&, const T&);
>> >
>> > take a const _reference_ as a second argument and rather than the most
>> > efficient of { T, const T& } ? It's less efficeint to pass a float by
>> > const reference rather than value IMHO.
>>
>> I don't think anything in the standard prevents a compiler from passing a
>> const reference parameter by value ...
>
>What about the following program:
>
>int i;
>void f(const int&);
>int main() { i=1; f(i); assert(i==2); }
>
>void f(const int& i) { const_cast<int&>(i)=2; }
>
>According to the standard, this program must work (the assertion may
>not fail: changing the reference obtained via with const_cast is well
>defined since the object itself is not const).

This doesn't apply to the complex functions: they are specified
not to change their arguments.  Thus, despite being declared
with const& arguments, they can be implemented as efficiently
as possible.  The only restriction is that for types with a
user-specified copy constructor or destructor, the implementation
isn't allowed to call it.

--
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: Theodore Todorov <todorov@sbghp10.in2p3.fr>
Date: 1998/05/14
Raw View
Daniel Parker wrote:
>
> Stuart I Reynolds wrote in message <355054FB.3D8D@cs.bham.ac.uk>...
> >Does anyone know why there isn't there a template version of the `abs'
> >function that works for all numbers, and not just ints? The stdlib one
> >just works for integers - which is a tad limited.
> >
> >e.g.
> >
> >template <class T>
> >T abs(const T& n)   //name conflicts with one on stdlib
>
> So put it in a different namespace, that's what namespaces are for.
>
> >{
> >  return  (n>T(0)) ? n : -n;
> >
> >}
> >
>
> I'd guess that basing an implementation of abs on the inequality operator
> might not be completely reliable for very small numbers since the minimum
> positive value of a double (numeric_limits<double>::min()) is orders of
> magnitude smaller than the smallest value epsilion such that 1 + epsilon > 1
> (numeric_limits<double>::epsilon()).  If you were implementing a version of
> abs, I'd suggest providing a specialization for float and double and
> implementing them in terms of ::fabs(), assuming of course that the compiler
> vendor knows what it's doing.  I'd be interested in hearing a response from
> someone with real numerical expertise.
>

There is no precision problem for floating types when comparing with 0,
since the compiler should know how to convert 0 to double (for example)
with the necessary precision (I hope this is explicit somewhere in the
standard)
Of course one should never compare for _equality_ with zero the result
of
a floating point computation and that's where the
numeric_limits<double>::epsilon() etc. is needed, but that's a
completely
different problem.

I wish abs() was defined as a template, but it looks like there is no
real
problem with that since one can either overload abs() for new types
or put the template in a namespace different from std and resolve the
ambiguity with a

  using  abspace::abs;

declaration in the body of the function that uses it
(in this case the template will be used even for int and float).

But the availability of abs for floating point types is already a huge
improvement!

                                  Regards,
                                               Teddy Todorov
(t.todorov@cern.ch)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/14
Raw View
> Yes. But this does not mean complex<int> *shall* not be intantiated. I
> can understand why instantiating complex for bool is meaningless. But

Complex for any unsigned type would be a problem too.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/05/14
Raw View
In article <6ja8m7$5s1@nrtphc11.bnr.ca>,
  "Cathy James" <Cathy.James.cajames@nt.com> wrote:
>
> >> I don't think anything in the standard prevents a compiler from passing a
> >> const reference parameter by value
>
> >But unless explicitly stated otherwise *the standard does NOT
> >allow the compiler to change the semantics of a program, even
> >slightly*.
>
>  In any case, there's definitely a difference in behavior.
> A const reference could use an explicit cast to remove the const and modify
> the original variable.  If passed by value, this wouldn't be possible,
> ergo, you're not compliant.

That's not a difference in "observable behavior", as long as the compiler
makes sure that any output uses the modified version.

In practice, of course, a compiler will probably only make the
change if 1) the called function doesn't cast away const and modify
the object, and 2) the program never takes the address of the called
function.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient=E9e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/14
Raw View
James Kuyper wrote:
>
> > Yes. But this does not mean complex<int> *shall* not be intantiated. I
> > can understand why instantiating complex for bool is meaningless. But
>
> Complex for any unsigned type would be a problem too.

No. It might be a problem for you that the results are not intuitive,
but that's another problem - the results of unary minus are not
intuitive
as well. I'd expect the following function to return UINT_MAX:

unsigned int f()
{
  complex<unsigned int> i(0,1);
  return real(i*i);
}

Of course, this doesn't need to compile at all.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/05/15
Raw View
Pete Becker wrote:
>
> Valentin Bonnard wrote:
> >
> > A.Stokes@globalcomm.co.uk wrote:
> >
> > > I don't think anything in the standard prevents a compiler from passing a
> > > const reference parameter by value
> >
> > References are references - that's all. Nothing in the standard
> > allow any perversion of their semantics.
>
> No, but the "as if" rule permits the suggested optimization for types
> without constructors or destructors.

I don't know the intended scope of the original statement, but
it's misleading at best (especially w/o its context).

The optimisation is possible in some particular cases, for example
complex<float>. In general, for user code, it isn't valid, even
for built-in types; a reference is another name of the same object,
the compiler isn't allowed to make a copy of it (with a different
identity, different address, ect).

--

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: jkanze@otelo.ibmmail.com
Date: 1998/05/15
Raw View
In article <3558935A.263A@pratique.fr>,
  Valentin Bonnard <bonnardv@pratique.fr> wrote:

> But unless explicitly stated otherwise *the standard does NOT
> allow the compiler to change the semantics of a program, even
> sligtly*.

Except that it is stated otherwise.  The standard does two things.
It defines the syntax of a legal program; a conforming implementation
must accept such programs (within its environment limits).  And it
defines the semantics of an abstract implementation; all that is
required of a conforming implementation, however, is that its
"observable behavior" be the same as that of the abstract implementation.
There is no requirement whatsoever concerning the "semantics".
(My interpretation here is based on the C standard, but I believe
that the C++ follows the same policy.)

The notion of observable behavior is very limited; basically, it
only concerns what would normally result in system calls (IO, principally)
and volitile variables.  An implementation is free to pass an
argument by value to a function declared to take the argument by
reference, provided the program output doesn't change.

--
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/   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: jkanze@otelo.ibmmail.com
Date: 1998/05/15
Raw View
In article <xaj67jb49ay.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:

> Hem. Since the Standard does not mandate an implementation to
> specialize complex for int , long int, end users have no portable
> way apart intanting them. They have to be optimistic and rely on a an
> speculative optimiser.

But we always rely on "optimization" from the compiler.  Even my
applications, which aren't really time critical, rely on the compiler
not inserting an empty 5 second loop after each line.

In practice, if the function is inline, I've never seen a compiler
that wouldn't change call by reference into call by value for a
basic type.  So all the library writer has to do to get this optimization
is to declare the function inline.  (For anything but a trivial function,
the difference in time between call by reference and call by value is
negligible.)

--
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/   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: jkanze@otelo.ibmmail.com
Date: 1998/05/15
Raw View
In article <3559447F.D9AAC653@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:

> What about the following program:
>
> // main.cc
>
> int i;
>
> void f(const int&);
>
> int main()
> {
>   i=3D1;
>   f(i);
>   assert(i=3D=3D2);
> }
>
> // f.cc
>
> void f(const int& i)
> {
>   const_cast<int&>(i)=3D2;
> }

This program has no observable behavior, so all that is required
is that the compiler generate a program without any observable
behavior.  A good compiler for an Intel platform, for example,
might generate:

    main:
        mov eax , 0
        ret

(For what it's worth, such compilers do exist, although perhaps not
for C++.  I actually used one for C about 10 years ago.)

Replacing the assert with cout << i, and a really clever compiler
will generate (on a UNIX platform) something the equivalent of:

   write( 1 , "2" , 1 ) ;

While I've never seen a compiler that good, it's not unreasonable to
expect the compiler to simply pass a constant 2 to
ostream::operator<<( int ).

Typically, I would not expect any compiler to generate a call to f
when optimization is requested.  Generating f inline requires less
code than the call, and so is always a win.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient=E9e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----=3D=3D Posted via Deja News, The Leader in Internet Discussion =3D=3D=
-----
http://www.dejanews.com/   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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/15
Raw View
Matt Austern wrote:
>
> > But unless explicitly stated otherwise *the standard does NOT
> > allow the compiler to change the semantics of a program, even
> > sligtly*.
>
> But with one big exception: the compiler may change the semantics
> however it likes, if there's no way to tell the difference.  (The "as
> if" rule.)

If there's no way to tell the difference, the semantics of the
program has not been changed...
---
[ comp.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: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/15
Raw View
>> > > I don't think anything in the standard prevents a compiler from passing a
>> > > const reference parameter by value
>> >
>> > References are references - that's all. Nothing in the standard
>> > allow any perversion of their semantics.
>>
>> No, but the "as if" rule permits the suggested optimization for types
>> without constructors or destructors.

How about this example:

int k=0;

void f() { ++k; }

void g(const int& i)
{
 int oldk = k;
 f();
 if( i == k )
  cout << "pass by reference\n";
 else if( i == oldk )
  cout << "pass by value\n";
 else
  cout << "can't happen\n";
}

int main()
{
 g(k);
}

---
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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/15
Raw View
jkanze@otelo.ibmmail.com wrote:
>
> In article <3559447F.D9AAC653@physik.tu-muenchen.de>,
>   Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> > What about the following program:
> >
> > // main.cc
> >
> > int i;
> >
> > void f(const int&);
> >
> > int main()
> > {
> >   i=1;
> >   f(i);
> >   assert(i==2);
> > }
> >
> > // f.cc
> >
> > void f(const int& i)
> > {
> >   const_cast<int&>(i)=2;
> > }
>
> This program has no observable behavior, so all that is required
> is that the compiler generate a program without any observable
> behavior.  A good compiler for an Intel platform, for example,
> might generate:
>
>     main:
>         mov eax , 0
>         ret
>
> (For what it's worth, such compilers do exist, although perhaps not
> for C++.  I actually used one for C about 10 years ago.)
>
> Replacing the assert with cout << i, and a really clever compiler
> will generate (on a UNIX platform) something the equivalent of:
>
>    write( 1 , "2" , 1 ) ;
>
> While I've never seen a compiler that good, it's not unreasonable to
> expect the compiler to simply pass a constant 2 to
> ostream::operator<<( int ).
>
> Typically, I would not expect any compiler to generate a call to f
> when optimization is requested.  Generating f inline requires less
> code than the call, and so is always a win.

Well, I did use two files (see comments!) for exactly this reason.
To trigger the difference for compilers with cross-module inlining,
you can put the file f.cc into a shared library. Since the compiler
cannot know what will be in the library as implementation of f, it
cannot optimize away anything. Especially it cannot optimize the call
by reference to a call by value, since it doesn't know if f changes
the value.

Of course, the compiler would be *allowed* to make the optimizations
you state. OTOH, between "allowed to" and "able to", there's still
a difference. For example, a compiler would be allowed to detect an
inefficient sort routine and replace it with an efficient one, since
the observable behaviour (after the call, the data is sorted) will
not change (this of course assumes that there's no other code during
sort, which might detect the differece, say, output of what the
algorithm currently does to cout for educational purposes). But how
to teach the compiler to detect inefficient sort algorithms?

(In the case of f(), the dynamic linker could invoke a compiler for
pre-compiled code, of course...)


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/15
Raw View
jkanze@otelo.ibmmail.com wrote:
>
> In article <3558935A.263A@pratique.fr>,
>   Valentin Bonnard <bonnardv@pratique.fr> wrote:
>
> > But unless explicitly stated otherwise *the standard does NOT
> > allow the compiler to change the semantics of a program, even
> > sligtly*.
>
> Except that it is stated otherwise.  The standard does two things.
> It defines the syntax of a legal program; a conforming implementation
> must accept such programs (within its environment limits).  And it
> defines the semantics of an abstract implementation; all that is
> required of a conforming implementation, however, is that its
> "observable behavior" be the same as that of the abstract implementation.
> There is no requirement whatsoever concerning the "semantics".
> (My interpretation here is based on the C standard, but I believe
> that the C++ follows the same policy.)

Well, the semantics of a program *is* its observable behaviour.
So changing the semantics of a program is indeed changing of its
observable behaviour (note that those would include replacing
constructs inside the program with others with different construct
semantics, as long as this doesn't change the semantics of the
program. Also note that the semantics of a program is *not* just
the "sum" of the semantics of the used constructs.)

>
> The notion of observable behavior is very limited; basically, it
> only concerns what would normally result in system calls (IO, principally)
> and volitile variables.  An implementation is free to pass an
> argument by value to a function declared to take the argument by
> reference, provided the program output doesn't change.

But this implies that the compiler can prove that the program output
doesn't change. Can you say "halting problem"?


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/15
Raw View
Christopher Eltschka wrote:
>
> Matt Austern wrote:
> >
> > > But unless explicitly stated otherwise *the standard does NOT
> > > allow the compiler to change the semantics of a program, even
> > > sligtly*.
> >
> > But with one big exception: the compiler may change the semantics
> > however it likes, if there's no way to tell the difference.  (The "as
> > if" rule.)
>
> If there's no way to tell the difference, the semantics of the
> program has not been changed...

That's starting to get into an argument about what is meant by the word
'semantics'. In this context, an optimization was suggested that
replaced a pass by reference with a pass by value, with compiler fix-ups
to make it look to the program just as if it had been a reference; to be
used only when the compiler can verify that the fix-ups will work. I'd
say that this is allowed.


[ comp.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: Gabriel Dos Reis <dosreis@DPTMaths.ens-cachan.fr>
Date: 1998/05/15
Raw View
>>>>> =ABJames=BB, jkanze  <jkanze@otelo.ibmmail.com> wrote:

James> In article <xaj67jb49ay.fsf@korrigan.inria.fr>,
James>   Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:

>> Hem. Since the Standard does not mandate an implementation to
>> specialize complex for int , long int, end users have no portable
>> way apart intanting them. They have to be optimistic and rely on a an
>> speculative optimiser.

James> But we always rely on "optimization" from the compiler.  Even my
James> applications, which aren't really time critical, rely on the compiler
James> not inserting an empty 5 second loop after each line.

James> In practice, if the function is inline, I've never seen a compiler
James> that wouldn't change call by reference into call by value for a
James> basic type.  So all the library writer has to do to get this optimization
James> is to declare the function inline.  (For anything but a trivial function,
James> the difference in time between call by reference and call by value is
James> negligible.)


1. complex<> and valarray<> were designed for scientific computing
were almost everything is time critical.

2. compilers which support type alias can hardly support such
kind of optimization and such compilers do exist.

3. Inlining does not always increase performance.

4. Even declaring such functions inline does not solve the problem if
type alias is allowed.

Too much is put on the compiler whereas it is possible to ease its
jobs w/o loosing anything.

-- Gaby


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/16
Raw View
Steve Clamage<clamage@Eng.Sun.COM> wrote:
 >>> > > I don't think anything in the standard prevents a compiler
 >>> > > from passing a const reference parameter by value
 >>> >
 >>> > References are references - that's all. Nothing in the standard
 >>> > allow any perversion of their semantics.
 >>>
 >>> No, but the "as if" rule permits the suggested optimization for types
 >>> without constructors or destructors.
 >
 >How about this example:
 >
 >int k=0;
 >
 >void f() { ++k; }
 >
 >void g(const int& i)
 >{
 > int oldk = k;
 > f();
 > if( i == k )
 >  cout << "pass by reference\n";
 > else if( i == oldk )
 >  cout << "pass by value\n";
 > else
 >  cout << "can't happen\n";
 >}
 >
 >int main()
 >{
 > g(k);
 >}

The "as if" rule doesn't help in this example.  The question was about
the case of real library functions, such as the functions that operate
on complex types.

There, the function is declared inline, and the compiler can examine
the body of the function and determine that no operations it performs
could modify the target of the reference argument.  Thus, it can keep
that value in a register, which resembles pass-by-value.

This is a normal (albeit aggressive) optimization.

--
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: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1998/05/16
Raw View
jkanze@otelo.ibmmail.com writes:

> Except that it is stated otherwise.  The standard does two things.
> It defines the syntax of a legal program; a conforming implementation
> must accept such programs (within its environment limits).  And it
> defines the semantics of an abstract implementation; all that is
> required of a conforming implementation, however, is that its
> "observable behavior" be the same as that of the abstract implementation.
> There is no requirement whatsoever concerning the "semantics".
> (My interpretation here is based on the C standard, but I believe
> that the C++ follows the same policy.)
>
> The notion of observable behavior is very limited; basically, it
> only concerns what would normally result in system calls (IO, principally)
> and volitile variables.  An implementation is free to pass an
> argument by value to a function declared to take the argument by
> reference, provided the program output doesn't change.


Formally an implementation is free to pass en argument by value to a
function declared to take the argument by reference (note that
refrence in a foreign concept to C) provided the program output
doesn't change, except that in C++ it does make a big difference
(semantically speaking and the semantic is part of the observable
behavior) to pass by a reference or by value, as a refrence is just
another the name of an object. How can you in general tell if there
will be no difference in the observable behavior if you pass by value
instead of refrence ? If the function has a side effect (or calls a
function with side effect), I'm afraid you could not give a warranty
in general...

-- Gaby
---
[ comp.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: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1998/05/17
Raw View
A.Stokes@globalcomm.co.uk writes:

>
> I don't think anything in the standard prevents a compiler from passing a
> const reference parameter by value (it can make a copy and bind the reference
> to that, and then eliminate the reference), and I would hope a good one would
> do so for small types.

Hum... What you suggest is a change in the semantics, even in abscence
of const_cast.

Let's assume for a reason X or Y I can't inline any function in:

// File: foo.H

class StrangeRing {
 int value;
public:
 StrangeRing(int i) : value (i) {}

 friend StrangeRing operator+(const StrangeRing&, const StrangeRing&);
 ...
};


// File: foo.C

#include "foo.H"

StrangeRing operator+(const StrangeRing& a, const StrangeRing& b)
{
 if (&a == &b) abort();
 else return StrangeRing(a.value + b.value);
}
...

Given separate compilation, I can hardly see how the compiler will
not change the semantics, thus the observable beahaviour, of a programm
involving operator+(const Strangering&, const StrangeRing&) with your
optimization on. Reference is reference i.e. another name of an object.


-- Gaby


[ comp.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: clamage@Eng.sun.com (Steve Clamage)
Date: 1998/05/06
Raw View
In article 3D8D@cs.bham.ac.uk, Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk> writes:
>Does anyone know why there isn't there a template version of the `abs'
>function that works for all numbers, and not just ints? The stdlib one
>just works for integers - which is a tad limited.

The C++ draft standard contains overloaded versions of abs for (almost)
all numeric types -- int, long, float, double, long double, complex,
and also for valarray.

I suppose nobody thought a general template version would be
widely useful.

---
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: "Daniel Parker" <danielp@nospam.com>
Date: 1998/05/06
Raw View
Stuart I Reynolds wrote in message <355054FB.3D8D@cs.bham.ac.uk>...
>Does anyone know why there isn't there a template version of the `abs'
>function that works for all numbers, and not just ints? The stdlib one
>just works for integers - which is a tad limited.
>
>e.g.
>
>template <class T>
>T abs(const T& n)   //name conflicts with one on stdlib

So put it in a different namespace, that's what namespaces are for.

>{
>  return  (n>T(0)) ? n : -n;
>
>}
>


I'd guess that basing an implementation of abs on the inequality operator
might not be completely reliable for very small numbers since the minimum
positive value of a double (numeric_limits<double>::min()) is orders of
magnitude smaller than the smallest value epsilion such that 1 + epsilon > 1
(numeric_limits<double>::epsilon()).  If you were implementing a version of
abs, I'd suggest providing a specialization for float and double and
implementing them in terms of ::fabs(), assuming of course that the compiler
vendor knows what it's doing.  I'd be interested in hearing a response from
someone with real numerical expertise.

--
Regards,
Daniel Parker danielp@no_spam.anabasis.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: jkanze@otelo.ibmmail.com
Date: 1998/05/06
Raw View
In article <355054FB.3D8D@cs.bham.ac.uk>#1/1,
  Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk> wrote:
>
> Does anyone know why there isn't there a template version of the `abs'
> function that works for all numbers, and not just ints? The stdlib one
> just works for integers - which is a tad limited.

I think you just answered your own question: the function is already
defined in the standard library -- it could be overloaded, but a
template would pose incompatibility problems with C.

--
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/   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: "Ross Smith" <ross.s@ihug.co.nz>
Date: 1998/05/07
Raw View
Stuart I Reynolds wrote in message <355054FB.3D8D@cs.bham.ac.uk>...
>Does anyone know why there isn't there a template version of the `abs'
>function that works for all numbers, and not just ints? The stdlib one
>just works for integers - which is a tad limited.

Your library is faulty. According to the draft standard, abs() is
supposed to be overloaded for int, long, float, double, and long double.

--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
  "Remember when we told you there was no future? Well, this is it."
                                                        -- Blank Reg
---
[ comp.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: clamage@Eng.sun.com (Steve Clamage)
Date: 1998/05/08
Raw View
In article BF757D1C@ix.netcom.com, "Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>Ross Smith wrote:
>>
>> Your library is faulty. According to the draft standard, abs() is
>> supposed to be overloaded for int, long, float, double, and long
>> double.
>
>I only see it for complex<T>, valarray<T>, float, double and long
>double. I don't see it for int or long.

The C++ draft standard in section 26.5 requires the following signatures
to be present in standard headers <cstdlib> and <stdlib.h>, in addition
to what is required by the C standard:

 long        abs(long);
 float       abs(float);
 double      abs(double);
 long double abs(long double);

Since the C standard requires an int version, it is not mentioned
explicitly.

---
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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/08
Raw View
Ross Smith wrote:
>
> Your library is faulty. According to the draft standard, abs() is
> supposed to be overloaded for int, long, float, double, and long
> double.

I only see it for complex<T>, valarray<T>, float, double and long
double. I don't see it for int or long.

It would seem to make sense for abs(int) to return unsigned int, and
abs(long) to return unsigned long, thus causing them to work correctly
on two's complement machines when given the maximum negative number. Any
comments?

--

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: antonio@Somewhere.@.USC (Antonio)
Date: 1998/05/08
Raw View
El 06 May 98 14:02:18 GMT, Stuart I Reynolds escribi=F3:
>Does anyone know why there isn't there a template version of the `abs'
>function that works for all numbers, and not just ints? The stdlib one
>just works for integers - which is a tad limited.
>
>e.g.
>
>template <class T>
>T abs(const T& n)   //name conflicts with one on stdlib
>{
>  return  (n>T(0)) ? n : -n;
>
>}
>
>Does everyone else end up writing their own version of this or is it
>just me?

  I use a similar trick, which does not conflict with the one on stdlib:

template <class T>
T Abs( const T & n )
{
  return (n>T(0)) ? n : -n ;
}

  By the way, I do use this one as well:

#ifdef _THIS_COMPILER_HAS_A_STD_COMPLEX
# include <complex.h>
typedef complex<float> Complex;
#else
# include <complex.h>
typedef complex Complex;
#endif

  Yep, I know it has nothing to do with the standard, but it's the
  only way I can use complex numbers on several platforms (yes,
  I'm using PVM and/or MPI for parallel processing) without
  modifying my code. The idea is to try to make things portable
  all through different C++ versions, and that is important when
  developping scientific applications.

  Hope it helps,

  Antonio


  P.S.: Does anyone know of an interesting (different, portable, faster)
        implementation of complex numbers I can use with C++?=20


[ comp.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: Stuart I Reynolds <S.I.Reynolds@cs.bham.ac.uk>
Date: 1998/05/06
Raw View
Does anyone know why there isn't there a template version of the `abs'
function that works for all numbers, and not just ints? The stdlib one
just works for integers - which is a tad limited.

e.g.

template <class T>
T abs(const T& n)   //name conflicts with one on stdlib
{
  return  (n>T(0)) ? n : -n;

}

Does everyone else end up writing their own version of this or is it
just me?

Stu.
---
[ comp.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              ]