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

6
  • #include <unistd.h> missing Commented Jul 19, 2013 at 8:24
  • @GrijeshChauhan I am using Visual Studios, we do not have that header file Commented Jul 19, 2013 at 8: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 Commented Jul 19, 2013 at 8: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. Commented Jul 19, 2013 at 8:29
  • @Tony D uhm arp_piping.h does have 16 lines, empty ones count as well Commented Jul 19, 2013 at 8:31

3 Answers 3

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);
Sign up to request clarification or add additional context in comments.

6 Comments

I am not windows programmer, but didn't get what is EXTERNC , what is this?
@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: stackoverflow.com/questions/1041866/…
@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 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
@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++.
|
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.

Comments

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"
}

2 Comments

extern "C" is used to tell the compiler to make it as C grammer No, it's not. It's about calling conventions and that's it.
what's your mean of calling conventions? can you explain it any more? thank you for your tip firstly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.