Skip to main content
GameDev.net gamedev.net
🔒 Locked

strncpy is declared deprecated

Started by ph33r Jun 12, 2005 at 7:59 PM 18 replies 8.4k views
Original Post
ph33r
ph33r
So was sprintf and all there related functions, is there any C alternatives I can use?
Zahlman
Zahlman
If you are writing in C++, use C++.

#include <string>#include <iostream>using namespace std;int main() {  string x = "y helo thar";   // implicitly invoked constructor: std::string(const char*)  string y;  y = x; // copies the string as per str*cpy-type functions  y[5] = 'l'; // omg I make dirty wr0d :(  cout << x << endl << y << endl;}


If you are writing in C, consult your compiler's documentation to determine how to make sure it understands that you want to write in C.
Omaha
Omaha
There is absolutely no reason not to use char arrays or pointers for string usage even if your code is native C++. If all you need to do is keep ahold of some text or have an easily accessed buffer without all the overhead of an entire data structure, I would recommend char arrays every time.

If you want to do lots of concatenation and inserting and stuff like that, then you might want to look into std::string or some other implementation of a string wrapper, but to say that using chars is not a good idea is spreading misinformation.

Added ESPECIALLY if you're going to expose the whole std namespace just to use the string class!
Apocryphiliac
Apocryphiliac
Quote:
Original post by ph33r
So was sprintf and all there related functions, is there any C alternatives I can use?


Okay people, before we get into a holy war over C++ strings, take a look at the original post. ph33r is asking for a C function.

Who has said that these functions are deprecated? Not that they shouldn't be for security reasons, but there's no standard cross-platform replacement yet.

If you really want to avoid strncpy but stay within the standard library, you could use strncat, just set the first character of the destination array to 0 and it should work just like strncpy.
Way Walker
Way Walker
Quote:
Original post by ph33r
So was sprintf and all there related functions, is there any C alternatives I can use?


Who says they're deprecated? If it's your compiler, tell it you're programming in C, not C++ (e.g. end your files with .c instead of .cpp or .C, or give gcc the option "-x C", or whatever). If it still says they're deprecated, it's probably prefering some platform specific extension (OpenBSD prefers strlcpy(), etc. which are not standard).

So, your options:
Use non-standard functions of C-strings (e.g. strlcpy())
Use non-standard strings in C (e.g. make a struct string { char *str; size_t len; }; sort of thing)
Use the "deprecated" C functions (What most C programmers do)
Use another language
snk_kid
snk_kid
It's pretty obvious where your getting those deprecated messages its from VC++ 8.0. Its not deprecated from the C or C++ standard as of yet only in VC++ 8.0 compiler they are deprecated to be completely replaced by the secure, safe versions yes there is a safe version of strncpy its:

strncpy_s


Yes you can use it now if you want.

All C I/O routines are deperecated and have safe/secure versions, they end with _s, these are being considered to be standardized in C and i think C++ too, read more about it Security Enhancements in the CRT and The Safe C library.

[Edited by - snk_kid on June 13, 2005 2:44:15 PM]
ph33r
ph33r
Thank you snk_kid, strncpy_s is what I was looking for. That article was an interesting read as well.
MaulingMonkey
MaulingMonkey
Quote:
Original post by Omaha
There is absolutely no reason not to use char arrays or pointers for string usage even if your code is native C++.


Wrong



1) If you use any function which has to find the end of the string (std::strlen, std::strcat, etc) there's a good to perfect chance std::string will outpreform since it stores the string's length. This changes appending a series of data to a string from an O(N*N) to an O(N) complexity operation - see "Joel on Software - Back to Basics" for a full explaination and history about the dreaded painters algorithm Shlemiel the painter's algorithm.

2) std::string manages it's memory. Randomly malloced char pointer? Welcome to memory leak city...

3) a = b + c; - works with std::string, causes a to point to a random memory location with char pointers. The C version?

a = malloc( strlen( b ) + strlen( c ) + 1 );strcpy( a , b );strcat( a , c );


That's no less than 3 lines of code, AND it uses the painters algorithm (which is bad, so there's a good chance "a = b + c" will outpreform this version), AND we're omitting the free( a ) statement which we must call or suffer a memory leak.

Also note that the first time I wrote that I accidentally missed the + 1, which meant it suffered a buffer overflow. ANOTHER reason not to use char pointers.

[Edited by - MaulingMonkey on June 13, 2005 2:28:24 PM]
moeron
moeron
Quote:
Original post by Omaha
Added ESPECIALLY if you're going to expose the whole std namespace just to use the string class!


It was just an example...I'm sure he's aware he could have just exposed the string class...
moe.ron
MaulingMonkey
MaulingMonkey
Quote:
Original post by Anonymous Poster
Quote:
Original post by MaulingMonkey
Quote:
Original post by Omaha
There is absolutely no reason not to use char arrays or pointers for string usage even if your code is native C++.


Wrong

1) If you use any function which has to find the end of the string (std::strlen, std::strcat, etc) there's a good to perfect chance std::string will outpreform since it stores the string's length. This changes appending a series of data to a string from an O(N*N) to an O(N) complexity operation - see "Joel on Software - Back to Basics" for a full explaination and history about the dreaded painters algorithm.

2) std::string manages it's memory. Randomly malloced char pointer? Welcome to memory leak city...

3) a = b + c; - works with std::string, causes a to point to a random memory location with char pointers. The C version?

a = malloc( strlen( b ) + strlen( c ) );
strcpy( a , b );
strcat( a , c );

That's no less than 3 lines of code, AND it uses the painters algorithm (which is bad, so there's a good chance "a = b + c" will outpreform this version), AND we're omitting the free( a ) statement which we must call or suffer a memory leak.


You do realize that Omaha's post doesn't disagree with anything you've said.


Yes it does. He says there's no reason not to use manual poniters, and I give these reasons:

1) std::string will likely outpreform for string manipulation, which
is what we're talking about. That is, manual pointers will be SLOWER.
2) char pointers are easy to leak. That is, manual pointers are more prone to bugs.
3) std::string is easier to use. That is, even the simplest manipulation of manual pointers is more complex (plus it's slower, see #1).

These are all good reason not to use manual pointers, which Omaha claimed do not exist. I have listed them as proof that there are reasons not to use them, dispelling this horrible claim (wheither actually intended or simply the result of not clearly expressing something else that was meant).

Quote:
He was saying that if you're just holding text or keeping a small buffer, std::string is overkill;


Doubtful, many (most?) string implementations implement small internal buffers (~16 bytes IIRC) which cuts down on allocations for such strings. If you want on-the-stack memory for quick (de)allocation, just use a stack allocator.

Quote:
Note that I'm not disagreeing with your overall argument. Whether by accident or intentional, the buffer overrun in (3) shows your point.


And I didn't even list that reason specifically. See how easy it is to misuse char pointers kids? That should've been "strlen( b ) + strlen( c ) + 1".

My point is that there's perfectly good reasons to avoid char pointers. Sure, if you've got a broken compiler for some obscure hardware architecture that dosn't optimize away the contents of an "if (0) { ... }" block, you may have better reasons to use char pointer/arrays than reasons not to. Regardless, even on such a craptastic platform, there WILL be reasons not to use char pointer/arrays. They just won't outweigh the reasons to use them.
MaulingMonkey
MaulingMonkey
Quote:
Original post by Oluseyi
Quote:
Original post by MaulingMonkey
see "Joel on Software - Back to Basics" for a full explaination and history about the dreaded painters algorithm.
Just FYI, Shlemiel the painter's algorithm is not the same thing as the Painter's algorithm.


Dear me, thanks for pointing that out.

*carries on*
MaulingMonkey
MaulingMonkey
Quote:
Original post by Anonymous Poster
What part of "If you want to do lots of concatenation and inserting and stuff like that, then you might want to look into std::string or some other implementation of a string wrapper" don't you understand? It wasn't a blanket statement.


I get that part just fine. The part I don't get is where he says "but to say that using chars is not a good idea is spreading misinformation."

Why? Because there's plenty of solid facts why using chars can be an exteremely bad idea.

Quote:
You also seem really caught up on this speed thing.


Ironically, this is the only argument I've ever seen for char pointer/arrays - and hence I am arguing on the assumption that the issue of speed is the reason char arrays are even been considered. I'm suprised that anyone would try to use them for any other reasons... besides machoism, anyways.

Quote:
Note that one can also optimize for space.


Of course that's just a method for optimizing for speed except for embeded environments. That's why I didn't say "don't ever use character arrays". But these seem to be the exception rather than the rule, so such a blanket statement as "there's no reason not to use chars" directly implies "there's not reason to use std::string" (because if there was, then the advantage(s) that made you choose std::string over the char array would be reasons not to use chars).

Omaha mentions "looking into" std::string so he's obviously not of that belief. I'm thus merely trying to point out the inconsistancy, and point out that there's plenty of reasons why one shouldn't blindly use character arrays directly.

Quote:
If you say the space gains are negligible, I'll just tell you that your speed gains are negligible (considering the average size of strings). For some string operations, it's entirely possible that the reduced overhead of arrays is faster (smaller constant).


And yet that dosn't disprove any of the reasons I've listed on why not to use char arrays.

Quote:
(I remember reading a comment in the STL headers that came with GCC saying that their list didn't give a length in constant time because they didn't want the overhead)


And yet that dosn't have anything to do with this conversation. Unless there's some implied sentiment that you've decided not to share explicitly with the rest of it.

Quote:
Quote:
These are all good reason not to use manual pointers, which Omaha claimed do not exist. I have listed them as proof that there are reasons not to use them, dispelling this horrible claim (wheither actually intended or simply the result of not clearly expressing something else that was meant).


Actually, he said that there's no reason not to use manual pointers in a given situation. If you hadn't snipped all the context, you would've seen that.


Maybe you're having a problem with the boolean grammar. "No reason not to __A__" indicates "No reason to __B__", where B is an opposite of A.

There are reasons to use std::string, which is an opposite of directly using char arrays. Is there any part of this you specifically disagree with.

Quote:
"Just use a stack allocator"? Many programmers here don't even know what an allocator is or how to properly use them.


And yet they should be trusted with allocating and managing memory themselves? That's a very laughable sentiment.

Quote:
I'm always torn when I use C++. Part of me loves all the machinery that you have to play with. Part of me loathes how hard it is to do such a simple thing "properly".


I'm always torn when I use C. Part of me loathes the fact that you have to reimplement simple things repeatedly, part of me realizes things could be worse - like I could be dead.

C++ dosn't force you to do anything "proper". If it did, it'd provide multiple std::strings optimized for different situations and completely eliminate char arrays. There wouldn't be a const_cast, either. If you want, you can write spaghetti code in 20 sub-dialects of 1337 and have e-penis measuring contests over who spends the most time debugging.

It's a good idea to learn how to do things properly, but only because it's meant to save you time in the long run. That said, nobody's forcing you. Deal with it.

Quote:
Quote:
Note that I'm not disagreeing with your overall argument. Whether by accident or intentional, the buffer overrun in (3) shows your point.


And I didn't even list that reason specifically. See how easy it is to misuse char pointers kids? That should've been "strlen( b ) + strlen( c ) + 1".


I say "I agree" and you keep arguing your point. Why?[/quote]

Where there am I arguing?

Quote:
Quote:

My point is that there's perfectly good reasons to avoid char pointers. Sure, if you've got a broken compiler for some obscure hardware architecture that dosn't optimize away the contents of an "if (0) { ... }" block, you may have better reasons to use char pointer/arrays than reasons not to. Regardless, even on such a craptastic platform, there WILL be reasons not to use char pointer/arrays. They just won't outweigh the reasons to use them.


It's not "some obscure hardware architecture" just because it's not something made by Intel.


Where did I say that?

If you're like me, you've probably heard of Macs, and don't consider them obscure in the slightest. If you somehow read into my words that I DID consider them obscure, then it is my sad duty to inform you that optimizing compilers have been around quite awhile for Macs. Unfortunately, just because it's not Intel dosn't mean you have a good reason for screwing around with horrible excuses for optimizations.

Quote:
On of the design goals of C was to work on "some obscure hardware architecture". It's sad that you're splitting straws about the phrasing "there's no reason". It usually (in my experience, I suppose yours may vary) means "given the pros and cons, there's no reason".


Since the pros and cons are undefined for the general situation, that's an extremely horribly overgeneralized statement made, then. Why? Because although N% of the time the pros will outweigh the cons, (100-N)% of the time it will not. I'm going to be extremely conservative and only claim that "N is less than 90" for the times that the pros of character arrays outweigh the cons.

I'm "splitting straws" to get a point accross.

Use char arrays when appropriate? Of course.

Use them blindly as some sacrificial offering to the gods of C in an attempt to resurrect shoddy programming practices best left for dead last millenia? I wouldn't, and it's my belief you probably don't want to either.
Will F
Will F
Quote:
Original post by Omaha
Added ESPECIALLY if you're going to expose the whole std namespace just to use the string class!


Correct me if i'm wrong, but doesn't the following use std::string without exposing the whole std namespace?

#include <iostream>#include <string>void Foo(){  std::string str("A String");  std::cout << str << std::endl;}
ph33r
ph33r
I don't know why you guys are arguing over this - you seem to agree on the same thing. My code can not be switched to use C++ style string's for memory reasons.

I'm reading and writing data and if I stored each node as a std::string their would be a overhead associated with each key name, when I know the exact size of the name the std::string is a complete waste, adding megabytes to each file. I load in huge chunks of memory at a time, so I can't convert from char[] to string's while loading, and to re-iterate through the entire data set to convert after words would add an extra O(n) operation over a large enough data set. For what I'm doing it is certainly not practical to use std::string.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.