popen неявно объявлено, хотя добавлен #include <stdio.h>

Это крошечный фрагмент моего кода.

   #include <stdio.h>
   #include <unistd.h>
   #include <stdlib.h>
   #include <time.h>
   #include <sys/stat.h>
   #include <sys/wait.h>
   #include <sys/types.h>
   #include <string.h>
   #include <sys/types.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <arpa/inet.h>
    ...

   FILE * pipe;
    ...

   pipe = popen ("ls /tmp -1", "r");
    ...
   pclose(pipe);

blarg.c:106: warning: implicit declaration of function ‘popen’

blarg.c:106: warning: assignment makes pointer from integer without a cast

blarg.c:112: warning: implicit declaration of function ‘pclose’

blarg.c:118: warning: assignment makes pointer from integer without a cast

Я действительно не уверен. Я посмотрел вверх popen, и все, что требуется, это stdio.h, который предоставляется. Чего не хватает, или проблема в остальной части моего кода (я действительно не хочу показывать больше кода, потому что это назначение).

5 ответов

Замещать -std=c99 или же -std=c11 и т.д. с -std=gnu99 или же -std=gnu11,

Как написано на странице руководства:

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

popen(), pclose(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE || _BSD_SOURCE
|| _SVID_SOURCE

Так что вы должны #define _BSD_SOURCE или один из других, прежде чем #includeИНГ stdio.h,

Я столкнулся с этой проблемой в MinGW; в его stdio.h я нашел:

      #ifndef NO_OLDNAMES
_CRTIMP __cdecl __MINGW_NOTHROW  FILE *  popen (const char *, const char *);
_CRTIMP __cdecl __MINGW_NOTHROW  int     pclose (FILE *);
#endif

И оказывается, у меня был-DNO_OLDNAMES=1в моей командной строке gcc, чтобы исправить какую-то неясную проблему в другом исходном файле, о которой я уже даже не могу вспомнить. Это было мое легкое решение:

      #ifdef NO_OLDNAMES
  #undef NO_OLDNAMES
#endif
#include <stdio.h>

Как прокомментировали другие, такие как @Conrad Mayer.

Кратко, просто добавьте

      #define _POSIX_C_SOURCE 200809L  // Define this before any includes

#include <stdlib.h>
... rest of code ...

Объяснение

Функция popen() является частью стандарта POSIX, и ее объявление может зависеть от правильного определения макросов проверки функций. Это должно гарантировать доступность необходимых объявлений для popen().

Если проблема не устранена, вы можете попробовать определить _GNU_SOURCE перед включением заголовков, поскольку popen() также является расширением GNU:

      #define _GNU_SOURCE
#include <stdlib.h> 
... 

Я поместил прототипы popen и pclose вверху моего кода. Казалось, это решило проблему.

Другие вопросы по тегам