I'm trying to use strndup
function, but I get the error
error: implicit declaration of function 'strndup' [-Werror=implicit-function-declaration]
I have searched around and found that it's not a standard function and therefore I have to compile with different flags. However, I receive same issue by compiling with the following:
-std=gnu11
-Wall
-Wextra
-Werror
-Wmissing-declarations
-Wmissing-prototypes
-Werror-implicit-function-declaration
-Wreturn-type
-Wparentheses
-Wunused
-Wold-style-definition
-Wundef
-Wshadow
-Wstrict-prototypes
-Wswitch-default
-Wunreachable-code
-D_GNU_SOURCE
I'm doing an assignment and therefore I have to use all these, but what I found is that I have to compile with '-D_GNU_SOURCE' for the error to go away, but it doesn't.
EDIT:
I have these included as well:
#define __STDC_WANT_LIB_EXT2__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
Would very much appreciate help to fix this.
The functions strdup
and strndup
are not yet part of Standard C. They are standardized in Posix.1-2008 and declared in <string.h>
on Posix systems. Did you include <string.h>
?
If your system does not provide these functions, you can define them yourself this way:
#include <string.h>
#include <stdlib.h>
char *strdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
if (p != NULL) {
memcpy(p, s, size);
}
return p;
}
char *strndup(const char *s, size_t n) {
char *p;
size_t n1;
for (n1 = 0; n1 < n && s[n1] != '\0'; n1++)
continue;
p = malloc(n + 1);
if (p != NULL) {
memcpy(p, s, n1);
p[n1] = '\0';
}
return p;
}
You may find that you can 'activate' the declarations of strndup()
et al by setting appropriate macros to request POSIX support:
#define _XOPEN_SOURCE 700
That strictly is for the X/Open SUS (Single Unix Specification), but that's usually what you want. Strictly enabling only POSIX functionality would require:
#define _POSIX_C_SOURCE 200809L
The -std=gnu11
compiler option usually enables all these (and other special options) by default, so the fact that you're running into problems suggests you may not have the functions available regardless.
If you don't have strndup()
available even with the enabling macros set before you include any headers, you can write your own version of the function. The tricky part is making the declaration available in a suitable header. However, as a band-aid, you could make it static
in the only source file that needs it. It is also easiest to implement if you have strnlen()
available. If you don't have strnlen()
either (a plausible problem), then you need to write that too, but the plain C version probably won't match the speed of an assembler version of strnlen()
— or use memchr()
.
strndup()
char *strndup(const char *str, size_t len)
{
size_t act = strnlen(str, len);
char *dst = malloc(act + 1);
if (dst != 0)
{
memmove(dst, str, act);
dst[act] = '\0';
}
return dst;
}
(I note that chqrlie shows a neat alternative using memchr()
instead of strnlen()
.)
strnlen()
size_t strnlen(const char *str, size_t len)
{
for (size_t size = 0; size < len; size++)
{
if (str[size] == '\0')
return size;
}
return len;
}
Without knowing your code, I guess that you forgot to include string.h
.
#include <string.h>
If you don't include the particular header, the declaration of the function strndup()
isn't visible to the compiler. Hence the error message of strndup()
not being declared.
Put the above line at the top of your code and it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With