Menu

#295 extern "C" used in include file prevents enumeration members from appearing in global scope

None
closed-rejected
nobody
None
5
2020-01-30
2018-03-22
Alex P
No

Hi,
This construct is used in many C files but somehow cscope is having problem with it:
extern "C" {
typedef enum EnumOne {
EnumOne_1,
EnumOne_2,
EnumOne_3
} EnumOne
}

I noticed that cscope cant find global definitions of EnumOne_1, etc. but can find EnumOne OK. It also does not have issues with defines declared in that scope. I am attaching test example that I created. It is very simple.
When I comment just extern "C" line, I get following output from cscope:

$ cscope -L1 '.*' test.h 
test.h .* 2 #define TEST_H
test.h .* 10 #define DEFINE_0 6
test.h .* 11 #define DEFINE_1 3
test.h .* 12 #define DEFINE_2 2
test.h .* 13 #define DEFINE_3 6
test.h .* 14 #define DEFINE_4 7
test.h .* 16 typedef enum test_enum {
test.h .* 17 test_0 = 1,
test.h .* 18 test_1 = 2,
test.h .* 19 test_2,
test.h .* 20 test_3,
test.h .* 21 test_4
test.h .* 22 } test_enum;

But when I uncomment that same line, I get following output:

$ cscope -L1 '.*' test.h 
test.h .* 2 #define TEST_H
test.h .* 10 #define DEFINE_0 6
test.h .* 11 #define DEFINE_1 3
test.h .* 12 #define DEFINE_2 2
test.h .* 13 #define DEFINE_3 6
test.h .* 14 #define DEFINE_4 7
test.h .* 16 typedef enum test_enum {
test.h .* 22 } test_enum;

As you can see all of the enumeration members are missing.
I think this is a valid issue as the extern "C" statement is common in the C includes that also have to be included in C++ projects and therefore must declare functions with C linkage.

Thank you,
Alex

1 Attachments

Discussion

  • Alex P

    Alex P - 2018-03-22

    I guess, there is already a bug with exactly the same content and it is not going to be fixed. I understand that cscope would require re-work to support this.
    Since cscope can recognize C++ classes it does support C++ to some extent. Maybe the solution to this problem is to look for following statements and take them out :

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    

    Basically take out everything that would be processed by the C++ compiler.

     
  • Alex P

    Alex P - 2018-03-22

    From the comment in the similar reported issue I gathered that brace { in the extern "C" statement makes cscope confused and it assumes that definitions are local. I have to disagree with this statement. In that case in my example test_enum definition would also be local but it is present in both cases. Same with defines, although defines may be treated differently internally.

     
  • Alex P

    Alex P - 2018-03-23

    Hello, this is a patch for this issue. I just look at "C" string that comes after extern and reset extern state. I tested it on a large project tree and there are no crashes or anything unusial. If I find better solution I will post it here.
    Can this patch be merged?

     
  • Hans-Bernhard Broeker

    • status: open --> closed-rejected
    • Group: -->
     
  • Hans-Bernhard Broeker

    There are at least 3 problems with that patch:
    1. it triggers on every occurance of "C"
    2. it blindly assumes that extern "C" will only ever appear with a { after it
    3. it blindly assumes that extern "C" { can only appear at the outermost bracelevel

     
  • Alex P

    Alex P - 2020-01-29

    Is there another fix possible for this issue? This is a valid issue since extern "C" statement is a valid C statement.

     
    • Hans-Bernhard Broeker

      extern "C" statement is a valid C statement.

      No, it's really not. That's why it's almost invariably enclosed in an

      #ifdef __cplusplus
      #endif
      

      bracket: so the C compiler never sees it.

       
  • Alex P

    Alex P - 2020-01-30

    extern is a C keyword. It serves two puposes - states that the variable is declared externally(outside of this file) and can specify the linkage type. extern "C" states that the variable or function has C linkage. It tell compiler that this function name should not be mangled. I thought there were other linkage types than just "C" but I couln't find any examples.
    What would be the proper fix in cscope for this? Take out all things between #ifdef __cplusplus/#endif?

     
    • Hans-Bernhard Broeker

      extern "C" states that the variable or function has C linkage.

      Yes. But only in the C++ language. In C that would a syntax error.

       

Log in to post a comment.