strdup error on g++ with c++0x
Asked Answered
M

5

8

I have some C++0x code. I was able to reproduce it below. The code below works fine without -std=c++0x however i need it for my real code.

How do i include strdup in C++0x? with gcc 4.5.2

note i am using mingw. i tried including cstdlib, cstring, string.h and tried using std::. No luck.

>g++ -std=c++0x a.cpp
a.cpp: In function 'int main()':
a.cpp:4:11: error: 'strdup' was not declared in this scope

code:

#include <string.h>
int main()
{
    strdup("");
    return 0;
}
Milagrosmilam answered 6/4, 2011 at 22:34 Comment(2)
Works on gcc 4.5.1. Try #include <cstring>` and using std::strdup, that's the "C++ way". (Still isn't an answer, though, since that should be valid too, IIRC.)Competency
@GMan: I modified my question. I tried it and no luck :(. As a temp solution i put extern C _CRTIMP char* __cdecl __MINGW_NOTHROW strdup (const char*) __MINGW_ATTRIB_MALLOC; in my headers. It works with that.Milagrosmilam
S
11

-std=gnu++0x (instead of -std=c++0x) does the trick for me; -D_GNU_SOURCE didn't work (I tried with a cross-compiler, but perhaps it works with other kinds of g++).

It appears that the default (no -std=... passed) is "GNU C++" and not "strict standard C++", so the flag for "don't change anything except for upgrading to C++11" is -std=gnu++0x, not -std=c++0x; the latter means "upgrade to C++11 and be stricter than by default".

Simoom answered 29/11, 2012 at 15:45 Comment(0)
M
10

strdup may not be included in the library you are linking against (you mentioned mingw). I'm not sure if it's in c++0x or not; I know it's not in earlier versions of C/C++ standards.

It's a very simple function, and you could just include it in your program (though it's not legal to call it simply "strdup" since all names beginning with "str" and a lowercase letter are reserved for implementation extensions.)

char *my_strdup(const char *str) {
    size_t len = strlen(str);
    char *x = (char *)malloc(len+1); /* 1 for the null terminator */
    if(!x) return NULL; /* malloc could not allocate memory */
    memcpy(x,str,len+1); /* copy the string into the new buffer */
    return x;
}
Malebranche answered 6/4, 2011 at 22:46 Comment(4)
its reserved yet its nonstandard!?Milagrosmilam
malloc may need a cast to char * (#5100169)Skittle
@Steve That's what I get for coding it as C because it's normally a C function. Yes, it needs a cast in C++.Malebranche
strdup not in ANSI C, #define feature test macro may not be the best choice, some other strdup-like may need other feature test (_GNU_SOURCE, _BSD_SOURCE, ...). Just implement it.Im
B
3

This page explains that strdup is conforming, among others, to the POSIX and BSD standards, and that GNU extensions implement it. Maybe if you compile your code with "-D_GNU_SOURCE" it works?

EDIT: just to expand a bit, you probably do not need anything else than including cstring on a POSIX system. But you are using GCC on Windows, which is not POSIX, so you need the extra definition to enable strdup.

Barreto answered 7/4, 2011 at 12:47 Comment(0)
D
1

add this preprocessor "_CRT_NONSTDC_NO_DEPRECATE" to Project Properties->C/C++ Build->GCC C++ Compiler->Preprocessor->Tool Settings

Don't forget to check Preprocessor Only(-E)

This worked for me on windows mingw32.

Demisemiquaver answered 20/4, 2016 at 5:50 Comment(1)
That's an MSVC flag.Phira
R
1

If using C++, consider using C++ headers. string.h is a C header, <cstring> is its C++ equivalent.

#include <cstdlib>
#include <cstring>
#include <cstdio>

int main()
{
    const char * first = "asdf qwerty";
    printf("%s\n", first);

    char * second = strdup(first);
    second[4] = '\0';
    printf("%s\n", second);

    free(second);
    return 0;
}

The above code compiles fine with GCC 9.4.0 g++ -Wall -Wextra -std=c++11.


Bonus meme: if you do want strdup() in C (before C23), use a GCC Feature Test Macro such as __STDC_WANT_LIB_EXT2__ or _POSIX_C_SOURCE. The former enables C-standard extensions, the latter enables POSIX extensions. It is important this macro be defined before any of your includes, as shown below.

To quote from strdup - cppreference.com:

... strdup is only guaranteed to be available if __STDC_ALLOC_LIB__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT2__ to the integer constant 1 before including string.h.

#define __STDC_WANT_LIB_EXT2__ 1
/* ...or...
 * #define _POSIX_C_SOURCE 200809L
 */

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

int main(void)
{
    const char * first = "asdf qwerty";
    printf("%s\n", first);

    char * second = strdup(first);
    second[4] = '\0';
    printf("%s\n", second);

    free(second);
    return 0;
}
Ruisdael answered 28/8 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.