473,320 Members | 2,052 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

overloading std C functions with a namespace

I am working with a large C++ program which, for reasons of backward
compatibility, uses C's printf and fprintf rather than iostreams.

For a certain type of build I want to provide new functions that
change the behaviour of printf and fprintf, and I planned to make them
available using a convenient namespace, called 'herring', say, like this:

using herring::printf;
using herring::fprintf;

Now, all the other classes and functions etc are in their own
namespace, called 'haddock' say. So all the code has the lines

namespace haddock{
...
}

around it. It would be most convenient to put the 'using' directives
just inside the 'namespace', like this:

#include <stdio.h>

namespace herring{
int printf(const char*, ...);
int fprintf(FILE*, const char*, ...);
}

namespace haddock{
using herring::fprintf;
using herring::printf;

void halibut(){

FILE *fp;
fprintf(fp, "hoho");
printf("haha");
}

}

But this does not work: g++ -c gives me

name.C: In function `void haddock::halibut()':
name.C:15: call of overloaded `fprintf(FILE*&, const char[5])' is
ambiguous
name.C:5: candidates are: int herring::fprintf(FILE*, const char*, ...)
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/stdio.h:307:
int fprintf(FILE*, const char*, ...)

on a bog-standard RH Linux box with g++ 3.2.1

However, this does work:

#include <stdio.h>

namespace herring{
int printf(const char*, ...);
int fprintf(FILE*, const char*, ...);
}

namespace haddock{
using herring::printf;

void halibut(){
using herring::fprintf;

FILE *fp;
fprintf(fp, "hoho");
printf("haha");
}

}

which is fine, but would mean I have to put the 'using' into every
function, rather than simply changing
namespace haddock{
to
namespace haddock{ using herring::fprintf; using herring::printf;
(which I can actually do in a single header file).

Anyway, my question is, why does the second code compile but not the
first?

Thanks.
Jul 22 '05 #1
7 3454
<zb*****@amtp.liv.ac.uk> wrote...
I am working with a large C++ program which, for reasons of backward
compatibility, uses C's printf and fprintf rather than iostreams.

For a certain type of build I want to provide new functions that
change the behaviour of printf and fprintf, and I planned to make them
available using a convenient namespace, called 'herring', say, like this:

using herring::printf;
using herring::fprintf;

Now, all the other classes and functions etc are in their own
namespace, called 'haddock' say. So all the code has the lines

namespace haddock{
...
}

around it. It would be most convenient to put the 'using' directives
just inside the 'namespace', like this:

#include <stdio.h>

namespace herring{
int printf(const char*, ...);
int fprintf(FILE*, const char*, ...);
}

namespace haddock{
using herring::fprintf;
using herring::printf;

void halibut(){

FILE *fp;
fprintf(fp, "hoho");
printf("haha");
}

}

But this does not work: g++ -c gives me

name.C: In function `void haddock::halibut()':
name.C:15: call of overloaded `fprintf(FILE*&, const char[5])' is
ambiguous
name.C:5: candidates are: int herring::fprintf(FILE*, const char*, ...)
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include/stdio.h:307:
int fprintf(FILE*, const char*, ...)

on a bog-standard RH Linux box with g++ 3.2.1

However, this does work:

#include <stdio.h>

namespace herring{
int printf(const char*, ...);
int fprintf(FILE*, const char*, ...);
}

namespace haddock{
using herring::printf;

void halibut(){
using herring::fprintf;

FILE *fp;
fprintf(fp, "hoho");
printf("haha");
}

}

which is fine, but would mean I have to put the 'using' into every
function, rather than simply changing
namespace haddock{
to
namespace haddock{ using herring::fprintf; using herring::printf;
(which I can actually do in a single header file).

Anyway, my question is, why does the second code compile but not the
first?


In the second case the 'using' directive inside 'void halibut()'
function _hides_ the declaration of any other 'fprintf', whereas
at a namespace 'haddock' scope no hiding is occurring.

I wrote this, and it seems logical to me, although I didn't confirm
with the Standard. Let the gurus correct me if I am wrong.

Victor
Jul 22 '05 #2
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<eNcqc.16605$qA.2058485@attbi_s51>...
[redacted]


Now, I'm not the language guru that Victor is, and probably never will
be, but if the OP had used

#include <cstdio>

instead of

#include <stdio.h>

Wouldn't printf/fprintf be in the std namespace, so that there would
be no ambiguity between (the imported) herring::printf and
std::printf, while with the latter (as posted case), we have the
ambiguity between (the imported) herring::printf and ::printf
Jul 22 '05 #3
red floyd wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<eNcqc.16605$qA.2058485@attbi_s51>...
[redacted]

Now, I'm not the language guru that Victor is, and probably never will
be, but if the OP had used

#include <cstdio>

instead of

#include <stdio.h>

Wouldn't printf/fprintf be in the std namespace, so that there would
be no ambiguity between (the imported) herring::printf and
std::printf, while with the latter (as posted case), we have the
ambiguity between (the imported) herring::printf and ::printf


You're correct. However, the OP stated that it's a legacy code, so it is
quite possible that he didn't want to change the includes. Besides, the
question was "why it's so", not "how to fix it". Aside from that, you're
absolutely right.

Victor
Jul 22 '05 #4
zb*****@amtp.liv.ac.uk wrote in message news:<c8**********@news.liv.ac.uk>...
I am working with a large C++ program which, for reasons of backward
compatibility, uses C's printf and fprintf rather than iostreams.

For a certain type of build I want to provide new functions that
change the behaviour of printf and fprintf, and I planned to make them
available using a convenient namespace, called 'herring', say, like this:

using herring::printf;
using herring::fprintf;


I'd handle this a little bit differently. I'd start by including
<cstdio> instead of stdio.h. This has versions of printf and fprintf
that live in the std namespace. So, by including both headers, we
have an std::printf and a herring::printf.

Then comes the trickery: we add a namespace alias:

namespace desired = herring;

Then our using declarations become:

using desired::fprintf;
using desired::printf;
using desired::puts;
using desired:: ...

and switching from one to the other only involves changing the alias
-- to switch back to using the standard functions, we just edit it to:

namespace desired = std;

and compiler deals with the rest automagically.
--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 22 '05 #5
On Tue, 18 May 2004 09:20:55 -0400, Victor Bazarov
<v.********@comAcast.net> wrote:
red floyd wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<eNcqc.16605$qA.2058485@attbi_s51>...
[redacted]

Now, I'm not the language guru that Victor is, and probably never will
be, but if the OP had used

#include <cstdio>

instead of

#include <stdio.h>

Wouldn't printf/fprintf be in the std namespace, so that there would
be no ambiguity between (the imported) herring::printf and
std::printf, while with the latter (as posted case), we have the
ambiguity between (the imported) herring::printf and ::printf


You're correct. However, the OP stated that it's a legacy code, so it is
quite possible that he didn't want to change the includes. Besides, the
question was "why it's so", not "how to fix it". Aside from that, you're
absolutely right.


Not to mention that very few compilers have conforming <cheader>
headers - mostly they just pull the global declarations into the
standard namespace with using declarations. e.g.

//common but non-conforming <cstdio>
#include <stdio.h>
namespace std
{
using ::printf;
using ::fprintf;
//etc.
}

Which is unhelpful for the OP.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #6
Thanks for your interest and interesting comments...
red floyd wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<eNcqc.16605$qA.2058485@attbi_s51>...
[redacted]
Now, I'm not the language guru that Victor is, and probably never will
be, but if the OP had used

#include <cstdio>

instead of

#include <stdio.h>

Wouldn't printf/fprintf be in the std namespace, so that there would
be no ambiguity between (the imported) herring::printf and
std::printf, while with the latter (as posted case), we have the
ambiguity between (the imported) herring::printf and ::printf

The thing that puzzles me is that, in the code I posted, the compiler
sees _no_ ambiguity between the printf's (and I've verified that
herring::printf is actually called) but it does for the
fprintf's. This looks like an anomaly to me.

Victor seems to suggest that putting the 'using' directive inside the
'namespace haddock{...}' scope should not hide the previous
declaration - as it does with printf, whereas putting it inside the
function should - as it does for both printf and fprintf. If this is
the case then it is the printf behaviour which anomalous.
You're correct. However, the OP stated that it's a legacy code, so it is
quite possible that he didn't want to change the includes. Besides, the
question was "why it's so", not "how to fix it". Aside from that, you're
absolutely right.


Not to mention that very few compilers have conforming <cheader>
headers - mostly they just pull the global declarations into the
standard namespace with using declarations. e.g.

//common but non-conforming <cstdio>
#include <stdio.h>
namespace std
{
using ::printf;
using ::fprintf;
//etc.
}


This is indeed what my version here does. Changing the header to
<cstdio> doesn't fix the problem in my toy code, although the argument
sounds sensible to me. In any case, as suggested, in the real code
there's no way I can easily go and change it everywhere, and I am sort
of resigned to not being able to get what I wanted.

Thanks again.

Jul 22 '05 #7
re********@yahoo.com (red floyd) wrote:
Now, I'm not the language guru that Victor is, and probably never will
be, but if the OP had used

#include <cstdio>

instead of

#include <stdio.h>

Wouldn't printf/fprintf be in the std namespace, so that there would
be no ambiguity between (the imported) herring::printf and
std::printf, while with the latter (as posted case), we have the
ambiguity between (the imported) herring::printf and ::printf


This was the intention of the standard but this was and is not common
practise: effectively, it is impossible to provide a standard C++ library
on top of a standard C library unless you have control over both which is
actually a rare case unless you drop the requirement of wrapping names in
namespace std. If I remember correctly, the standardization committee
recently removed the requirement that the C names are only in namespace
'std' if you include <cstdio>.

Actually, I argued that it should be possible to implement a standard C++
library on top of a standard C library and still get the names in namespace
'std'. This would look something like this - I thought:

// <cstdio>
namespace std {
#include "/usr/include/stdio.h"
}

// <stdio.h>
#include <cstdio>
using std::printf;
// ...

Unfortunately, this does not really work out: the standard C headers tend
to contain names which are not part of the standard C++ library. Thus,
something like this would not work:

#include <unistd.h>

because <unistd.h> internally includes some C library headers and cannot
resolve the corresponding names later. The alternative of using a using
statement rather than a using declaration, ie. 'using namespace std'
conflicts with requirements for other standard C++ library headers. The
third alternative, including "/usr/include/stdio.h" twice also does not
work:

// <stdio.h>
#include <cstdio> // for names in namespace std
#include "/usr/include/stdio.h" // for non-nested names

because the resulting types become incompatible:

FILE* fp = std::fopen("foo", "r");

Concerning the original problem, I would guess that there is no viable
solution.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Terje Slettebø | last post by:
To round off my trilogy of "why"'s about PHP... :) If this subject have been discussed before, I'd appreciate a pointer to it. I again haven't found it in a search of the PHP groups. The PHP...
4
by: Dave Theese | last post by:
Hello all, I'm trying to get a grasp of the difference between specializing a function template and overloading it. The example below has a primary template, a specialization and an overload. ...
2
by: Nimmi Srivastav | last post by:
There's a rather nondescript book called "Using Borland C++" by Lee and Mark Atkinson (Que Corporation) which presents a rather good discussion of typecast operator overloading. I am presenting...
4
by: hall | last post by:
I accidently overloaded a static member function that I use as predicate in the std::sort() for a vector and ended up with a compiler error. Is this kind of overload not allowed for predicates and...
13
by: matthias_k | last post by:
Hi, I've never thought about this before, but since you are able to overload a function only by changing the const-ness of the formal parameters, some annoying side effects will arise. For...
10
by: Pantokrator | last post by:
Hi, Is there any way to "overload" a struct? e.g. having already struct stA1 { int i_ID; int i_Type; };
15
by: lordkain | last post by:
is it possible to do some kind of function overloading in c? and that the return type is different
11
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. ...
8
by: yashwant pinge | last post by:
#include<iostream> using namespace std; class base { public: void display() { } };
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.