4

I have looked at other posts and to be honest I am still not sure what is causing the problem. I am programming in Visual Studio and

I have the following code: (this is a C main)

int main(int arc, char **argv) {
       struct map mac_ip;
       char line[MAX_LINE_LEN];

       char *arp_cache = (char*) calloc(20, sizeof(char));   //yes i know the size is wrong - to be changed
       char *mac_address = (char*) calloc(17, sizeof(char));
       char *ip_address = (char*) calloc(15, sizeof(char));

       arp_cache = exec("arp -a", arp_cache);

It uses the following cpp code:

#include "arp_piping.h"

extern "C" char *exec(char* cmd, char* arp_cache, FILE* pipe) {
    pipe = _popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[128];
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL) {
              strcat(arp_cache, buffer);
        }
    }
    _pclose(pipe);
    return arp_cache;
}

With the matching header file:

#ifndef ARP_PIPING_H
#define ARP_PIPING_H
#endif

#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif

#include <stdio.h>
#include <string.h>

extern "C" char *exec(char* cmd, char* arp_cache, FILE* pipe);

#undef EXTERNC

But I keep on getting the following errors:

1>d:\arp_proto\arp_proto\arp_piping.h(14): error C2059: syntax error : 'string'
1>main.c(22): warning C4013: 'exec' undefined; assuming extern returning int
1>main.c(22): warning C4047: '=' : 'char *' differs in levels of indirection from 'int'

Please can I get some help, I have looked at other posts regarding the c2059 but am still getting nowhere

cxzp
  • 652
  • 2
  • 14
  • 28
  • `#include ` missing – Grijesh Chauhan Jul 19 '13 at 08:24
  • @GrijeshChauhan I am using Visual Studios, we do not have that header file – cxzp Jul 19 '13 at 08:25
  • If you define an `EXTERNC` macro for C++, why don't you use it? Furthermore, if `#ifndef ARP_PIPING_H` is supposed to be an include guard, the `#endif` needs to be at the end of the header. As is now, you prevent the double definiton of `ARP_PIPING_H` but that doesn't do anything – user2573221 Jul 19 '13 at 08:28
  • 1
    You're showing us 12 lines of `arp_piping.h` and the compilation error's reported at line 14. Defining your own "exec" is confusing as there are similarly named standard library function, though it shouldn't cause any particular trouble. You're not showing us the `#include` statements for `main.c`. – Tony Delroy Jul 19 '13 at 08:29
  • @Tony D uhm `arp_piping.h` does have 16 lines, empty ones count as well – user2573221 Jul 19 '13 at 08:31
  • @user2573221: ahhh... the stack overflow background code formatting job hasn't kicked in for me so I see a blob without any empty lines, but hitting "edit" on the question I see you're right - thanks! So, the error's from `extern "C" char *exec(char* cmd, char* arp_cache, FILE* pipe);` which doesn't even mention the word "string". cxzp: I recommend you use `gcc -E` or similar to see the preprocessor output - it may show some substitutions that explain how that line has failed. – Tony Delroy Jul 19 '13 at 08:34

3 Answers3

3

Change your exec declaration to use the EXTERNC macro you have taken pains to define.

EXTERNC char *exec(char* cmd, char* arp_cache, FILE* pipe);
jxh
  • 69,070
  • 8
  • 110
  • 193
  • I am not windows programmer, but didn't get what is `EXTERNC` , what is this? – Grijesh Chauhan Jul 19 '13 at 08:43
  • 1
    @GrijeshChauhan `EXTERNC` here resolves to `extern "C"`, which makes a function name have C linkage so it can be used in C programs. This is not a Windows specific feature! Read more here: http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c – user2573221 Jul 19 '13 at 09:04
  • @GrijeshChauhan: `EXTERNC` expands to `extern "C"` when compiled with a C++ compiler, and expands to nothing otherwise. So, C code sees a regular function declaration, while C++ sees a special declaration that indicates the declaration is for a symbol with C linkage (that is, don't mangle the name when trying to resolve the symbol). – jxh Jul 19 '13 at 16:53
  • @jxh actually this is what I not understand *`while C++ sees a special declaration that indicates the declaration is for a symbol with C linkage`* ? what does it means? In c++ `EXTERNC char *exec(ch` will expands as `extern "C" char *exec(ch` what is the meaning of `extern "C"` ?? how its useful for c++ compiler/code – Grijesh Chauhan Jul 19 '13 at 17:06
  • @GrijeshChauhan: It is how C++ code can call C library functions. It is also sometimes used to provide C code with a functional interface to something that was implemented in C++. – jxh Jul 19 '13 at 17:09
  • @jxh Ah! Now I got it! its to share library functions. Thanks helpful. – Grijesh Chauhan Jul 19 '13 at 17:17
2

I ran into this compilation error when adding an enum to a project. It turned out that one of the values in the enum definition had a name clash with a preprocessor #define.

The enum looked something like the following:


// my_header.h

enum Type 
{
   kUnknown,
   kValue1,
   kValue2
};

And then elsewhere there was a #define with the following:


// ancient_header.h

#define kUnknown L"Unknown"

Then, in a .cpp somewhere else in the project, both of these headers were included:


// some_file.cpp

#include "ancient_header.h"
#include "my_header.h"

// other code below...


Since the name kUnknown was already #define'd, when the compiler came to the kUnknown symbol in my enum, it generated an error since the symbol was already used to define a string. This caused the cryptic syntax error: 'string' that I saw.

This was incredibly confusing since everything appears to be correct in the enum definition and compiles just fine on it's own.

It didn't help that this was in a very large C++ project, and that the #define was being transitively included in a completely separate compilation unit and was written by someone 15 years ago.

Obviously, the right thing to do from here is rename that terrible #define to something less common than kUnknown, but until then, just renaming the enum value to something else works as a fix, e.g.:


// my_header.h

enum Type 
{
   kSomeOtherSymbolThatIsntDefined,
   kValue1,
   kValue2
};

Anyway, hopefully this answer is helpful for someone else, since the cause of this error stumped me for a good day and a half.

pje
  • 2,458
  • 1
  • 25
  • 26
0

extern "C" is used to tell the compiler to make it as C grammer, but your mean is to declear a extern function called exec. you just make fusion to the differ of this. so rewrite your code like this in arp_piping.h:

/*extern "C"*/ char *exec(char* cmd, char* arp_cache, FILE* pipe);

and then del the preffix of extern "C" in cpp file. if you want to comiler them with C grammer, just setting in the cpp which call for the function exec, so write like this:

extern "C" {
   #include "arp_piping.h"
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
DarkHorse
  • 161
  • 1
  • 12