std::abs ambiguity

Discussion in 'C++' started by Kaba, Apr 27, 2009.

  1. Kaba

    Kaba Guest

    Hi,

    Anyone knows why the 'abs' function is ambiguous here? Tried to compile
    with both Visual Studio 2008 Sp1 and Comeau. Ignore the fact that
    Own::abs does not do the right thing.

    The way I see it, the Standard Library abs should be in namespace std,
    the Koenig lookup shouldn't activate for native types, and thus there
    should be no ambiguity.

    #include <cmath>

    namespace Own
    {

    float abs(float x)
    {
    return x;
    }

    }

    using namespace Own;

    int main()
    {
    float a = 5;
    float b = 3;
    float c = abs(a - b);

    return 0;
    }


    --
    http://kaba.hilvi.org
     
    Kaba, Apr 27, 2009
    #1
    1. Advertising

  2. Kaba

    red floyd Guest

    Kaba wrote:
    > Hi,
    >
    > Anyone knows why the 'abs' function is ambiguous here? Tried to compile
    > with both Visual Studio 2008 Sp1 and Comeau. Ignore the fact that
    > Own::abs does not do the right thing.
    >
    > The way I see it, the Standard Library abs should be in namespace std,
    > the Koenig lookup shouldn't activate for native types, and thus there
    > should be no ambiguity.
    >
    > #include <cmath>
    >
    > namespace Own
    > {
    >
    > float abs(float x)
    > {
    > return x;
    > }
    >
    > }
    >
    > using namespace Own;
    >
    > int main()
    > {
    > float a = 5;
    > float b = 3;
    > float c = abs(a - b);
    >
    > return 0;
    > }


    Most implementations also put the Standard C library routines into the
    global namespace as well.
     
    red floyd, Apr 27, 2009
    #2
    1. Advertising

  3. Kaba

    Kaba Guest

    red floyd wrote:
    > Most implementations also put the Standard C library routines into the
    > global namespace as well.


    Thanks. Better to avoid using names from Standard Library then...

    --
    http://kaba.hilvi.org
     
    Kaba, Apr 27, 2009
    #3
  4. Kaba

    Bo Persson Guest

    Kaba wrote:
    > red floyd wrote:
    >> Most implementations also put the Standard C library routines into
    >> the global namespace as well.

    >
    > Thanks. Better to avoid using names from Standard Library then...


    Or perhaps better avoid using "using namespace xxx"?


    Bo Persson
     
    Bo Persson, Apr 27, 2009
    #4
  5. Kaba

    Guest

    On Apr 27, 8:41 am, "Bo Persson" <> wrote:
    > Kaba wrote:
    > > red floyd wrote:
    > >> Most implementations also put the Standard C library routines into
    > >> the global namespace as well.

    >
    > > Thanks. Better to avoid using names from Standard Library then...

    >
    > Or perhaps better avoid using "using namespace xxx"?


    Both are probably good ideas considering he'd hit the same problem if
    the call to abs was in the same namespace as his abs function.
     
    , Apr 27, 2009
    #5
  6. Kaba

    Fred Zwarts Guest

    "Kaba" <> wrote in message news:...
    > Hi,
    >
    > Anyone knows why the 'abs' function is ambiguous here? Tried to compile
    > with both Visual Studio 2008 Sp1 and Comeau. Ignore the fact that
    > Own::abs does not do the right thing.
    >
    > The way I see it, the Standard Library abs should be in namespace std,
    > the Koenig lookup shouldn't activate for native types, and thus there
    > should be no ambiguity.
    >
    > #include <cmath>
    >
    > namespace Own
    > {
    >
    > float abs(float x)
    > {
    > return x;
    > }
    >
    > }
    >
    > using namespace Own;
    >
    > int main()
    > {
    > float a = 5;
    > float b = 3;
    > float c = abs(a - b);
    >
    > return 0;
    > }


    The g++ compiler under Suse Linux (x86_64) Enterprise 10 handles this without any message.
    Maybe your compiler needs a switch to make it standard conforming.
     
    Fred Zwarts, Apr 28, 2009
    #6
  7. Kaba

    Kaba Guest

    Fred Zwarts wrote:
    > The g++ compiler under Suse Linux (x86_64) Enterprise 10 handles this without any message.
    > Maybe your compiler needs a switch to make it standard conforming.


    I have already disabled language extensions. I suspect this is something
    that is there because of some historical reasons. Most often, the Comeau
    compiler acts correctly. That it doesn't hints towards a good reason to
    do so.

    --
    http://kaba.hilvi.org
     
    Kaba, Apr 28, 2009
    #7
  8. Kaba

    James Kanze Guest

    On Apr 28, 12:58 pm, Kaba <> wrote:
    > Fred Zwarts wrote:
    > > The g++ compiler under Suse Linux (x86_64) Enterprise 10
    > > handles this without any message. Maybe your compiler needs
    > > a switch to make it standard conforming.


    > I have already disabled language extensions. I suspect this is
    > something that is there because of some historical reasons.
    > Most often, the Comeau compiler acts correctly. That it
    > doesn't hints towards a good reason to do so.


    It depends on the library implementation.

    Note that this is one place where C and C++ different, despite
    the fact that <cmath> is a "C" library header. In C, there is
    no function "abs" in <math.h>. And the one in <stdlib.h> only
    takes int, so would be a less good match. Roughly speaking, I
    think an implementation can take three approaches:

    -- It is fully conforming, all of the functions in the <c...>
    header are in namespace std::, and only in namespace std::.
    The program is legal.

    For a number of reasons, this is the case for very few
    implementations of the library, and none of the widespread
    ones.

    -- It puts all of the names in the <c...> headers in :: as
    well. Systematically. This is the case for Dinkumware, for
    example.

    -- Some of the functions (most of those directly inherited from
    C) are in both :: and std::, others (typically the overloads
    introduced by C++) are only in std::. This seems to be the
    most frequent implementation, even if it results in some
    incoherence.

    The next version of the standard will make all three approaches
    legal. So it's anyone's guess as to whether a given bit of code
    will actually work on another compiler or not.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 29, 2009
    #8
  9. Kaba

    Guest

    On Apr 29, 1:28 am, James Kanze <> wrote:
    >  -- It is fully conforming, all of the functions in the <c...>
    >     header are in namespace std::, and only in namespace std::.
    >     The program is legal.
    >
    >     For a number of reasons, this is the case for very few
    >     implementations of the library, and none of the widespread
    >     ones.
    >
    >  -- It puts all of the names in the <c...> headers in :: as
    >     well.  Systematically.  This is the case for Dinkumware, for
    >     example.
    >
    >  -- Some of the functions (most of those directly inherited from
    >     C) are in both :: and std::, others (typically the overloads
    >     introduced by C++) are only in std::.  This seems to be the
    >     most frequent implementation, even if it results in some
    >     incoherence.
    >
    > The next version of the standard will make all three approaches
    > legal.  So it's anyone's guess as to whether a given bit of code
    > will actually work on another compiler or not.


    Really? That seems most atrocious.
     
    , Apr 29, 2009
    #9
  10. Kaba

    James Kanze Guest

    On Apr 30, 12:53 am, wrote:
    > On Apr 29, 1:28 am, James Kanze <> wrote:
    > > The next version of the standard will make all three
    > > approaches legal. So it's anyone's guess as to whether a
    > > given bit of code will actually work on another compiler or
    > > not.


    > Really? That seems most atrocious.


    It's already the case for a lot of other things. Ideally, one
    would like the same rule as in C---a header is allowed to define
    what it is required to define, and nothing else. Practically,
    that's not implementable---you can't very well define
    std::vector (in <vector>) without a definition for the default
    allocator (in <memory>) or std::reverse_iterator (in
    <iterator>); if the compiler doesn't support export, you
    might also need <new> (or more likely, <memory> requires <new>,
    so you get it indirectly). So the rule was adopted that any C++
    header can include any other. So there are all sorts of code
    which compiles with one implementation, and not with another,
    because the author forgot to include a header.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 30, 2009
    #10
  11. "James Kanze" <> wrote in message
    news:...
    Roughly speaking, I
    think an implementation can take three approaches:

    <snipped other two>

    -- Some of the functions (most of those directly inherited from
    C) are in both :: and std::, others (typically the overloads
    introduced by C++) are only in std::. This seems to be the
    most frequent implementation, even if it results in some
    incoherence.

    What does/will be allowed to do an implementation taking this
    route for the overloads introduced by C++ when including the
    *.h form of the headers (which I believe you recently recommended)?

    I'm struggling to see how it could include the overloads in the *.h
    file - where they should be in :: - but leaves them only in std:: in the
    c* header, without going out of its way to do that, meaning that
    someone sees an advantage in the above approach for other than
    ease of implementation.

    Or I'm missing something.
     
    Christopher Dearlove, Apr 30, 2009
    #11
  12. * Christopher Dearlove:
    > "James Kanze" <> wrote in message
    > news:...
    > Roughly speaking, I
    > think an implementation can take three approaches:
    >
    > <snipped other two>
    >
    > -- Some of the functions (most of those directly inherited from
    > C) are in both :: and std::, others (typically the overloads
    > introduced by C++) are only in std::. This seems to be the
    > most frequent implementation, even if it results in some
    > incoherence.
    >
    > What does/will be allowed to do an implementation taking this
    > route for the overloads introduced by C++ when including the
    > *.h form of the headers (which I believe you recently recommended)?


    It's allowed in C++0x, that's the whole point of the change: to allow the
    existing practice.

    Specifically, the C++0x draft language regarding [xxx.h] in §D.5 is

    <quote>
    2 Every C header, each of which has a name of the form name.h, behaves as if
    each name placed in the standard library namespace by the corresponding cname
    header is placed within the global namespace scope. It is unspecified whether
    these names are first declared or defined within namespace scope (3.3.5) of the
    namespace std and are then injected into the global namespace scope by explicit
    using-declarations (7.3.3).
    3 [Example: The header <cstdlib> assuredly provides its declarations and
    definitions within the namespace std. It may also provide these names within the
    global namespace. The header <stdlib.h> assuredly provides the same declarations
    and definitions within the global namespace, much as in the C Standard. It may
    also provide these names within the namespace std. —endexample]
    </quote>

    I think it's a bit unclear what the "library namespace" is.

    As with C++98, the non-normative example is more clear than the normative text!


    > I'm struggling to see how it could include the overloads in the *.h
    > file - where they should be in :: - but leaves them only in std:: in the
    > c* header, without going out of its way to do that, meaning that
    > someone sees an advantage in the above approach for other than
    > ease of implementation.


    You're talking about an implementation conforming to C++98?

    One approach I can think of is to use two helper headers [basic_c_xxx.h] and
    [basic_cpp_xxx.h]. Then [cxxx] includes both those. [xxx.h] includes
    [basic_c_xxx.h], and also includes [basic_cpp_xxx.h] if this is C++. It may play
    around with macro definitions to remove [basic_c_xxx.h] namespace'ing when the
    language is C. When the language is C++ it uses 'using' directives to bring the
    names from some internal namespace and into the global namespace.

    Assuming that works nicely, and I can't see why not, it isn't difficult. As is
    oft stated, the solution to every computer science problem is indirection. :)


    > Or I'm missing something.


    Dunno, dunno even if I understood your question, but


    Cheers, & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, Apr 30, 2009
    #12
  13. "Alf P. Steinbach" <> wrote in message
    news:gtbrpn$1rt$-september.org...
    > You're talking about an implementation conforming to C++98?


    I was talking about de facto C++98 and de jure C++0X according to James's
    third model.

    > Assuming that works nicely, and I can't see why not, it isn't difficult.
    > As is oft stated, the solution to every computer science problem is
    > indirection. :)


    There's enough detail there for me to see how to do it. Why anyone
    would want to do it (as you are deliberately setting out to follow that
    model rather than the other two) is less clear, though I suppose it may
    relate to being able to compile more C programs written not aware of
    C++ with a C++ compiler (those using abs in various ways for example).

    Thanks.
     
    Christopher Dearlove, Apr 30, 2009
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop

    std::exit Ambiguity?

    JKop, Sep 27, 2004, in forum: C++
    Replies:
    10
    Views:
    2,551
    Ron Natalie
    Sep 27, 2004
  2. Steven T. Hatton
    Replies:
    4
    Views:
    3,905
    Rob Williscroft
    Dec 5, 2004
  3. Klaas Vantournhout

    f2c's abs conflicts with <complex> abs

    Klaas Vantournhout, Oct 31, 2006, in forum: C++
    Replies:
    3
    Views:
    388
    Victor Bazarov
    Oct 31, 2006
  4. John Doe

    std::abs problem

    John Doe, Mar 19, 2007, in forum: C++
    Replies:
    13
    Views:
    1,212
    P.J. Plauger
    Mar 21, 2007
  5. Philipp Klaus Krause

    multiple definition of `std::abs(long)'

    Philipp Klaus Krause, Jan 25, 2009, in forum: C++
    Replies:
    1
    Views:
    725
    Philipp Klaus Krause
    Jan 25, 2009
Loading...

Share This Page