How to tell if function has been declared?

S

Simon Elliott

Is there a way at compile time to determine if a function has been
declared?

My specific reason for this is because of memicmp() and stricmp() which
are declared in namespace std by some compilers but not by others. I
tried this but evidently didn't work:

#ifndef memicmp
int memicmp(const void *s1, const void *s2, size_t n);
#endif
 
V

Victor Bazarov

Simon said:
Is there a way at compile time to determine if a function has been
declared?

There is no way.
My specific reason for this is because of memicmp() and stricmp() which
are declared in namespace std by some compilers but not by others. I
tried this but evidently didn't work:

#ifndef memicmp
int memicmp(const void *s1, const void *s2, size_t n);
#endif

Of course it didn't.

I can only recommend this macro (assuming 1 and 2 put it in std and 3 and
4 don't):

#if defined(COMPILER_ONE) || defined(COMPILER_TWO)
#define MYmemicmp std::memicmp
#define MYstricmp std::stricmp
#elif defined(COMPILER_THREE) || defined(COMPIER_FOUR)
#define MYmemicmp memicmp
#define MYstricmp stricmp
#else
#error "Compiler unknown"
#endif

(or something like that), and then use 'MYmemicmp' in your code. The
COMPILER_ONE and other macros are the ones defined for those compilers
specifically, check the compiler documentation.

BTW, there are no standard functions 'memicmp' and 'stricmp', you do know
that, don't you?

V
 
S

Sherm Pendley

I can only recommend this macro (assuming 1 and 2 put it in std and 3 and
4 don't):

#if defined(COMPILER_ONE) || defined(COMPILER_TWO)

Yuck - That's fragile, and will break as soon as Compiler Two stops putting
non-standard functions in std.
#else
#error "Compiler unknown"

Even worse! Since when is an unknown compiler an error?

A better approach - which, contrary to the "no way" assertion above, is in
common use in thousands of applications - is to use autoconf.

In a nutshell, you write a shell script that tries to compile and run a tiny
test app that uses the function you're testing for. If the test app builds
OK and produces the expected output, the script returns a zero, otherwise a
non-zero.

Autoconf produces a "configure" script - you've probably run many of them
without ever worrying about how they were produced. Among other things, this
script takes a config.h.in file as input, runs a series of test scripts as
described above, and produces a config.h header with various macros either
included or commented, to reflect the results of the tests.

For instance, your config.h.in might contain:

#define HAVE_MEMICMP

This would either be copied as-is to config.h, or commented out, depending on
the result of the check for memicmp().

The autoconf approach is *far* less fragile than checking for specific OS and/
or compiler versions, and stands a much better chance of success on an unknown
OS and/or compiler.

Have a look here for more:
said:
BTW, there are no standard functions 'memicmp' and 'stricmp'

All the more reason to check for it at compile-time. Instead of making code
that's dependent on non-standard functions, it can take advantage of them if
they're available, or use more portable standards-based alternatives if not.

sherm--
 
V

Victor Bazarov

Sherm said:
Yuck - That's fragile, and will break as soon as Compiler Two stops putting
non-standard functions in std.

Yes. Non-standard behaviour (putting non-standard functions in 'std')
cannot be countered with anything standard. As soon as any compiler-
specific solution stops working, it has to be attended and re-worked.
That's why it's _compiler-specific_.
Even worse! Since when is an unknown compiler an error?

It's an error for this particular code -- an indicator that the unknown
compiler has to be factored into this conditional block. As soon as you
add it, there will be no more error.
A better approach - which, contrary to the "no way" assertion above, is in
common use in thousands of applications - is to use autoconf.

What's 'autoconf'? I've never heard of it and I've been programming in
C++ for more than 10 years.
In a nutshell, you write a shell script

On what operating system? Mine doesn't have a "shell" or a "script". And
if it does, the operating system on a system right next to mine either
doesn't, or has a different one.
> [...]
BTW, there are no standard functions 'memicmp' and 'stricmp'


All the more reason to check for it at compile-time. Instead of making code
that's dependent on non-standard functions, it can take advantage of them if
they're available, or use more portable standards-based alternatives if not.

Which "more portable standard-based alternatives" are those? 'autoconf'?

What I suggested is taking care of the situation in the _code_. What you
are suggesting is the use of an external tool not necessarily available on
the system. How is it "better"?

V
 
A

Andre Kostur

What's 'autoconf'? I've never heard of it and I've been programming
in C++ for more than 10 years.

See autoconf/automake, popularly used on many *NIX platforms (I've seen
Linux, Solaris, and HP/UX...) to determine which functions (and
libraries...) are available on the platform that you are currently
compiling on. Basically you run some sort of "configure" script before
compiling and it generates a config.h file with a whole bunch of #defines
representing what is and is not available. (But then we're going _way_
off-topic....)
Which "more portable standard-based alternatives" are those?
'autoconf'?

To OP: If autoconf doesn't know about your platform, then you're still
out of luck. You'll still need to implement those functions on your own.
What I suggested is taking care of the situation in the _code_. What
you are suggesting is the use of an external tool not necessarily
available on the system. How is it "better"?

However, I'm with you. If you're doing platform (or compiler) -specific
#ifdefs, cause an error at the end if you don't recognize the compiler.
Better to blow up and cause one to examine the code to see if it's right
on a new compiler than to hope that it happens to work out... (which may
result in suboptimal implementations..... the code may have to assume a
C++-written function versus some carefully hand-crafted asm code which
may take full advantage of perhaps, say, a crypto co-processor....
(hypothetically speaking) )
 
S

Simon Elliott

See autoconf/automake, popularly used on many *NIX platforms (I've
seen Linux, Solaris, and HP/UX...) to determine which functions (and
libraries...) are available on the platform that you are currently
compiling on. Basically you run some sort of "configure" script
before compiling and it generates a config.h file with a whole bunch
of #defines representing what is and is not available. (But then
we're going way off-topic....)

I need to support win32 compilers, so autoconf isn't really an option.

Thanks for all the suggestions and comments.

Boost comes with an interesting set of config files where various
vagaries and conformities of quite a few compilers are specified. But
boost have thousands of users who have tested against their compilers.

Instead of the suggested
#ifdef SOMETHING
#define MYmemicmp std::memicmp
#endif

would I be better doing something like this (I haven't tried to compile
this yet)?
#ifdef SOMETHING
namespace std
{
static inline int memicmp(const void *s1, const void *s2, size_t n)
{
return(MYmemicmp(s1, s2, n));
}
}
#endif

Or is it evil to add functions to namespace std? (In which case what
about those compilers, eg Borland C++ Builder, which do this?)

I realise that my version reverses the assignment of MYmemicmp and
std::memicmp, but I've got a ton of legacy code locked into other
developers' revision control, and I don't think I can go through it all
and get rid of all the std::memicmp references.
 
S

Sherm Pendley

Victor Bazarov said:
What's 'autoconf'? I've never heard of it

Have you heard of Google?
What I suggested is taking care of the situation in the _code_. What you
are suggesting is the use of an external tool not necessarily available on
the system. How is it "better"?

No tool is universally "better" for everyone.

Autoconf is very useful if you need to write code that can configure and build
on a wide range of common OS/compiler combinations, including Unix variants,
Windows, Mac OS X, and others.

If that's not what you need to do, then autoconf is not so useful - for you.

sherm--
 
V

Victor Bazarov

Simon said:
[..]
Or is it evil to add functions to namespace std? (In which case what
about those compilers, eg Borland C++ Builder, which do this?)

It's not evil. It's only illegal.

Implementors of the language (compiler creators) have much more
latitude when it comes to what they are allowed to do than mere
mortals that _use_ the compilers.

V
 
D

Dave Rahardja

Simon said:
[..]
Or is it evil to add functions to namespace std? (In which case what
about those compilers, eg Borland C++ Builder, which do this?)

It's not evil. It's only illegal.

Illegal? Nothing prevents it. It's merely unwise. ;-)

By the way, the discussion on autoconf, while interesting, has nothing to do
with the C++ language and should be taken to a different forum.
 
A

Andre Kostur

Simon said:
[..]
Or is it evil to add functions to namespace std? (In which case what
about those compilers, eg Borland C++ Builder, which do this?)

It's not evil. It's only illegal.

Illegal? Nothing prevents it. It's merely unwise. ;-)

I thought there was a clause kicking around where mere mortals (as in not
compiler-writers) were not permitted to add additional identifiers to the
std:: namespace...
By the way, the discussion on autoconf, while interesting, has nothing
to do with the C++ language and should be taken to a different forum.

Only mentioned by way of explanation to Victor.... it's definitely in the
realm of platform-specific (even if it is many platforms.... :) )
 
M

msalters

Simon Elliott schreef:
Is there a way at compile time to determine if a function has been
declared?

My specific reason for this is because of memicmp() and stricmp() which
are declared in namespace std by some compilers but not by others. I
tried this but evidently didn't work:

Yes, although it's a nasty one. IIRC, the trick is to provide a worse
alternative. E.g you provide an alternative memicmp with an ellipsis
parameter. This is done inside your own memicmp.cpp. You probably
want a using namespace std; in there as well. memicmp.h declares
only my::memicmp, which hides all this nastyness.

HTH,
Michiel Salters
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top