tags:

views:

188

answers:

3

Hi, I met some compilation error but do not know what the problem is. The code seems not use exception, but the error is about it.

//in misc.h:
char *basename(char *name); // line 94

// in misc.cc:
char *basename(char *name) {   // line 12
  char *result = name;  
  while(*name) {  
    if(*name == '/') result = name + 1;  
    name++;  
  }  
  return result;  
}  

Compilation error

g++ -pipe -W -Wall -fopenmp -ggdb3 -O2  -c -o misc.o ../../src/misc.cc  
../../src/misc.cc: In function ‘char* basename(char*)’:  
../../src/misc.cc:12: error: declaration of ‘char* basename(char*)’ throws different exceptions  
../../src/misc.h:94: error: from previous declaration ‘char* basename(char*) throw ()’  
make: *** [misc.o] Error 1

Does someone have some clue? Thanks and regards!


EDIT: Files included in misc.h are

#include <iostream>  
#include <cmath>  
#include <fstream>  
#include <cfloat>  
#include <stdlib.h>  
#include <string.h>

EDIT: in misc.i generated by -E option,

extern "C++" char *basename (char *__filename)  
     throw () __asm ("basename") __attribute__ ((__nonnull__ (1)));  
extern "C++" __const char *basename (__const char *__filename)
     throw () __asm ("basename") __attribute__ ((__nonnull__ (1)));
# 640 "/usr/include/string.h" 3 4
# 1 "/usr/include/bits/string3.h" 1 3 4
# 23 "/usr/include/bits/string3.h" 3 4
extern void __warn_memset_zero_len (void) __attribute__((__warning__ ("memset used with constant zero length parameter; this could be due to transposed parameters")));
# 48 "/usr/include/bits/string3.h" 3 4
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__, __artificial__)) void * 
memcpy (void *__restrict __dest, __const void *__restrict __src, size_t __len) throw ()  

{  
  return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));  
}  
...  
# 641 "/usr/include/string.h" 2 3 4  
...
+2  A: 

" ../../src/misc.h:94: error: from previous declaration ‘char* basename(char*) throw ()’ "

I'm reading that as having been declared twice, once with throw() and once without.

taspeotis
"basename" is only defined once in misc.h, and no "throw" in the entire file.
Tim
+1  A: 

Compiles for me, same flags. g++ (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4

Your error says that there is a declaration of ‘char* basename(char*) throw ()’

try opening misc.h and searching for throw in the entire file, to see if you put the throw in yourself and just forgot about it.

Chris H
Did not find "throw" in misc.h and misc.cc.
Tim
+4  A: 

You may be picking up the definition of basename() from libgen.h. On my OpenSUSE system, the version in libgen.h is defined with "throw ()" at the end (via the __THROW macro).

One thing you can try is to tell gcc to only run the preprocessor stage by adding the -E flag and then search for basename to see what is being defined:

g++ -pipe -W -Wall -fopenmp -ggdb3 -O2  -E -o misc.i ../../src/misc.cc  

If that is happening, you'll either need to drop the include of libgen.h, match the throw specifier or change the name of your function.

R Samuel Klatchko
Thanks, Samuel. So I change the name of my function and now I can compile it successfully. Still wondering though. I don't explicitly include libgen.h in any of the source files. So is it implicitly included in every C++ program and g++ or it is some other system library? Is it possible to find out which system library file making the confusion?
Tim
C requires that headers are independent; C++ does not. So, any C++ header can include any other - and that may be what is happening. Use the preprocessor only suggestions to see what is going on.
Jonathan Leffler
Thanks, Jonathan! By "C requires that headers are independent" do you mean in C a header cannot include another header? What can it say when preprocessing is successful while the compilation gives error like mine?
Tim
@Tim - to find out who is including libgen.h, first you should just run the preprocessor (using the -E flag mentioned in my answer). Then look at the file generated (misc.i as done in my example) and look for a line like "# _number_ /path/to/libgen.h (note that _number_ will be a number and not the text _number_). Then look at the line just before that line which should mention the header file including libgen.h.
R Samuel Klatchko
@Samuel: Thanks! Did not find "libgen.h" in misc.i. How does one know which library could also declare the same function as mine?
Tim
@Tim - do you see basename() anywhere in misc.i?
R Samuel Klatchko
Yes, Samuel. See my edit to the post. So what it can tell about which library file also has defined the same function? Is it string.h?
Tim
@Tim - to definitely tell, I would need to see some data that comes before the definition of basename. Specifically, you want to look at the *last* "# linenumber file" that comes *before* the definition of basename. The file mentioned there is your culprit.
R Samuel Klatchko
@Tim - I just looked on my system and see a definition of basename in string.h, so that is your culprit. It's hard to drop string.h as it's so common, so renaming basename() is your best bet.
R Samuel Klatchko