Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::abs ambiguity

0 views
Skip to first unread message

Kaba

unread,
Apr 27, 2009, 9:41:25 AM4/27/09
to
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

red floyd

unread,
Apr 27, 2009, 9:53:23 AM4/27/09
to

Most implementations also put the Standard C library routines into the
global namespace as well.

Kaba

unread,
Apr 27, 2009, 10:30:10 AM4/27/09
to
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

Bo Persson

unread,
Apr 27, 2009, 11:41:46 AM4/27/09
to
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


joshua...@gmail.com

unread,
Apr 27, 2009, 1:38:48 PM4/27/09
to

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.

Fred Zwarts

unread,
Apr 28, 2009, 6:09:53 AM4/28/09
to
"Kaba" <no...@here.com> wrote in message news:MPG.245fe27d3...@news.cc.tut.fi...

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.

Kaba

unread,
Apr 28, 2009, 6:58:53 AM4/28/09
to
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

James Kanze

unread,
Apr 29, 2009, 4:28:01 AM4/29/09
to

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:james...@gmail.com
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

joshua...@gmail.com

unread,
Apr 29, 2009, 6:53:01 PM4/29/09
to
On Apr 29, 1:28 am, James Kanze <james.ka...@gmail.com> 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.

James Kanze

unread,
Apr 30, 2009, 4:48:36 AM4/30/09
to

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.

Christopher Dearlove

unread,
Apr 30, 2009, 4:54:03 AM4/30/09
to
"James Kanze" <james...@gmail.com> wrote in message
news:be15a7bf-0156-4f13...@b7g2000pre.googlegroups.com...

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.


Alf P. Steinbach

unread,
Apr 30, 2009, 5:44:12 AM4/30/09
to
* Christopher Dearlove:

> "James Kanze" <james...@gmail.com> wrote in message
> news:be15a7bf-0156-4f13...@b7g2000pre.googlegroups.com...
> 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!

Christopher Dearlove

unread,
Apr 30, 2009, 8:19:49 AM4/30/09
to
"Alf P. Steinbach" <al...@start.no> wrote in message
news:gtbrpn$1rt$1...@news.eternal-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.


0 new messages