I'm trying to use functions from mman.h in my c code. The code compiles fine with g++/clang++, but when using gcc/clang it says that memfd_create has not been declared, however the code still runs fine.
I tried compiling online with godbolt and it's the same as locally, so I doubt it's something wrong with my setup. Does anyone know why this is happening? I'm using gcc 11.3 and clang 14.
#include <stdint.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <sys/mman.h>
int main()
{
int32_t fd = memfd_create("", 0);
if (fd == -1)
{
printf("Error creating fd\n");
return -1;
}
return 0;
}
Compile warning:
main.c:9:15: warning: implicit declaration of function 'memfd_create' is invalid in C99 [-Wimplicit-function-declaration]
int32_t fd = memfd_create("", 0);
_GNU_SOURCE has to be before any #include. See man feature_test_macros.
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
Related
I'm trying to use the memfd_create syscall in my C code. I tried to include sys/memfd.h as the man page for memfd_create says is appropriate, but GCC gives me an error "sys/memfd: No such file or directory".
I've tried Googling around and couldn't find anyone having the same problem. I noticed some versions of the manpage for memfd_create say that I should include sys/mman.h, but it didn't seem to help when I tried it. It would say memfd_create was implicitly declared.
Here is a minimal reproduction of my problem.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/memfd.h>
int main(){
int fd;
fd = memfd_create("test", MFD_CLOEXEC);
return 0;
}
I expect the above code to compile and run without error.
On older systems, you'll have to include linux/memfd.h for the MFD_ defines, and call memfd_create() via the the syscall(2) wrapper (and include unistd.h and sys/syscall.h for it work).
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/memfd.h>
#include <err.h>
int main(void){
int fd;
if((fd = syscall(SYS_memfd_create, "test", MFD_CLOEXEC)) == -1)
err(1, "memfd_create");
return 0;
}
The Ubuntu man-pages in Bionic (18.04) are not up to date with this API (including its implementation in Bionic).
The Focal man-page correctly shows how to include memfd_create(). It says:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/mman.h>
So you only need to include <sys/mman.h>, and you need to build with -D_GNU_SOURCE in your compiler flags. Or, do as the man page says and literally #define _GNU_SOURCE before including the header. However, I recommend just compiling with -D_GNU_SOURCE instead.
I've created a c project and this is the beginning of the main.c file:
#include <curl/curl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "include/httpdef.h"
//...some code
The httpdef.h beginning is this:
#ifndef httpdef
#define httpdef
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
//definitions
#endif
At the very first line of both files I get the error from the gcc compiler:
macro name must be an identifier
What could be the problem?
EDIT: I realized now that actually the compiler doesn't give any error, it's my vim plugin (YouCOmpleteMe) that generates this error. If I compile everything works and the error doesn't appear
Here's my code:
#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char** argv) {
sigignore(SIGTERM);
return 0;
}
Why do I get the following warning and how could I remove it?
implicit declaration of function ‘sigignore’
[-Wimplicit-function-declaration] sigignore(SIGTERM);
The program must be compiled like this: gcc -o foo.o foo.c.
Thanks
Man sigignore tells you to use #define _XOPEN_SOURCE 500 to enable sigignore. More on X/Open can be found here
The function you want to call has been marked as obsolete 15 years ago. The normal way to discourage people from using those functions (without actually breaking programs) is to have the implementation of the function left in the standard library, but remove the declaration from header files (or at least make it hard to enable).
Use sigaction or sigprocmask (depending on what you actually want to accomplish).
This is tiny snippet of my code.
#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
I'm really unsure. I looked up popen and all it requires is stdio.h which is provided. What is missing, or is the problem in the rest of my code (I don't really want to show more code because its an a assignment).
As the man page says:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
popen(), pclose(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE || _BSD_SOURCE
|| _SVID_SOURCE
So you should #define _BSD_SOURCE or one of the others before #includeing stdio.h.
Replace -std=c99 or -std=c11 etc with -std=gnu99 or -std=gnu11.
I put the prototypes of popen and pclose at the top of my code. It seemed to have settled the problem.
a cpp file:
#include <iostream>
#include <jni.h>
#include "Hello.h"
#include "windows.h"
#include "stdafx.h"
typedef void(__stdcall *Print_)();
int main(){
HINSTANCE hDll; //DLL句柄
Print_ print_; //函数指针
hDll = LoadLibrary("Hello.dll");
if (hDll != NULL)
{
print_ = (Print_)GetProcAddress(hDll,"Java_Hello_sayHello#8");
if(print_!=NULL)
{
print_();
}
FreeLibrary(hDll);
}
return 0;
}
//there is something wrong, it prints:
http://i983.photobucket.com/albums/ae311/keatingWang/c_wrong.png
未声明的标识符 means : Undeclared identifier
Consider the macro:
#define HINSTANCE "hDll"
and its use:
HINSTANCE hDll; //DLL句柄
after preprocessing it would look like:
"hDll" hDll;
which clearly is an error as it makes hDll undeclared as "hDll" is not a valid type.
Could it be a pre-compiled header issue? With some project settings VC++ will skip stuff before the #include "stdafx.h", which I think might be the cause of the C4627 warnings you're getting. Have you tried moving #include "stdafx.h" before your other #includes?
remove
#define HINSTANCE "hDLL"
To remove C4627 warning, move up #include "stdafx.h" to the top (to be the first #include) as indicated by Mike Dinsdale's answer. This will probably solve error for LoadLibrary, GetProcAddress, and FreeLibrary:
#include "stdafx.h" // moved up
#include <iostream>
#include <jni.h>
#include "Hello.h"
#include "windows.h"