Search code examples
c++gccpopen

too many arguments to function 'FILE* popen()' in C++


I wrote a little test program which compiles and runs as expected when compiled with GCC:

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

#define BUFFSZ 512

int ping_test(char *host);

int main(void) {
    if (ping_test("192.168.1.1"))
        printf("PING OK!\n");
    else
        printf("PING FAIL!\n");



}

// returns 1 if ping succeeds, 0 otherwise
int ping_test(char *host)
{
    FILE *in;
    int i = 0;
    int ok = 1;
    extern FILE *popen();
    char buff[BUFFSZ] = {0};
    char res[BUFFSZ] = {0};
    char cmd[50]={0};

    sprintf(cmd,"ping -c 1 %s",host);
    if(!(in = popen(cmd, "r"))){
            exit(1);
    }
    while(fgets(buff, sizeof(buff), in)!=NULL){
            strcat(res,buff);
    }   
    pclose(in);
    printf("RESULT: %s\n",res);
    // check for string "100%"
    for (i=0;i<BUFFSZ;i++) {
        if (res[i] == '\%' && 
            res[i-1] =='0' &&
            res[i-2] =='0' &&
            res[i-3] =='1'){
            ok = 0;
        return ok;
        } else
            ok = 1;
    }
    return ok;
}

now I'd want to use this same function in a Qt C++ program I'm working on, so I copied the function into a private method in my class:

int JTFTestSuite::Ping(char *host)
{
    FILE *in;
    int i = 0;
    int ok = 1;
    extern FILE *popen();
    char buff[BUFFSZ] = {0};
    char res[BUFFSZ] = {0};
    char cmd[BUFFSZ]={0};

    sprintf(cmd,"ping -c 1 %s",host);
    if(!(in = popen(cmd, "r"))){
            exit(1);
    }
    while(fgets(buff, sizeof(buff), in)!=NULL){
            strcat(res,buff);
    }
    pclose(in);
    printf("RESULT: %s\n",res);
    // check for string "100%"
    for (i=0;i<BUFFSZ;i++) {
        if (res[i] == '\%' &&
            res[i-1] =='0' &&
            res[i-2] =='0' &&
            res[i-3] =='1'){
            ok = 0;
        return ok;
        } else
            ok = 1;
    }
    return ok;
}

declaration in header:

private:
    int Ping(char *host);

but now, it doesn't compile, the compiler complains with:

error: too many arguments to function 'FILE* popen()'
     if(!(in = popen(cmd, "r"))){
                             ^

Why is this I'm wondering? The includes are identical in both source files


Solution

  • In C, you can declare a function without declaring any particular prototype, by using an empty parameter list. (You shouldn't do this. It has been deprecated for a long time. But you can.) If you want to declare a function which takes no parameters, you need to use void as the parameter list.

    This doesn't work in C++. In C++, an empty parameter list means the function takes no arguments.

    So in C,

    FILE* popen();  // unspecified what the parameters are
    FILE* f = popen(cmd, "r");   // called with two strings
    

    In C++

    FILE* popen();  // takes no arguments
    FILE* f = popen(cmd, "r");   // illegal because popen takes no argument.
    

    Rather than declaring popen (and other library functions) yourself, #include the correct header file. popen and pclose are in <stdio.h>, but you need to make sure you define the correct feature test macro before any #includes. (#define _XOPEN_SOURCE 700 will work, for example.)