Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Soricidus
Oct 21, 2010
freedom-hating statist shill
doesn't alter the fact that drepper is fundamentally right: you can only handle variable-length data safely if you know its length, and if you know its length then there's no point using functions that rely on null termination. so the only c-string function you should be using is strlen(), when someone else gives you a c string and you need to find out its length in order to start handling it safely. having a "safe" strcpy just encourages people to carry on using c strings for purposes other than interfacing with legacy code.

Adbot
ADBOT LOVES YOU

Vanadium
Jan 8, 2005

Syscalls are legacy code now? :(

Soricidus
Oct 21, 2010
freedom-hating statist shill
what else would you call an interface that was designed decades ago and would be impractical to change?

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Vanadium posted:

Syscalls are legacy code now? :(

The legaciest.

Vanadium
Jan 8, 2005

Well it's not like they stopped making new syscalls and I haven't really seen anything take not-C strings.

Soricidus
Oct 21, 2010
freedom-hating statist shill
i'm saying people shouldn't use c strings in new interfaces. the fact that they do it anyway is beside the point.

and it seems likely that consistent string handling within a project leads to fewer bugs overall than trying to use null-terminated strings in some parts and explicit lengths in others, so sticking to c strings might be the right choice for an existing os -- but that's still going to be due to the presence of large amounts of legacy code. linus' main objection that started this whole topic was that changing existing code to use a better interface is inherently dangerous, even if the new interface is theoretically better.

Soricidus fucked around with this message at 17:42 on Sep 13, 2015

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I'd argue that most code does not want "copy this C string but truncate it to this sized C string". It wants "copy up to N bytes of this other buffer into this sized C string". strlcpy might look like it does the latter, but in fact it does the former.

ExcessBLarg!
Sep 1, 2001

Soricidus posted:

doesn't alter the fact that drepper is fundamentally right: you can only handle variable-length data safely if you know its length
The caller code doesn't actually need to know the length (of the source string), it just needs to know if truncation has or will occur. That also ignores scenarios where truncation, while regrettable, is still the best thing to do (e.g., writing a log message that exceeds the length of the log buffer--it's still better to have the first N bytes than none of it).

Soricidus posted:

and if you know its length then there's no point using functions that rely on null termination. so the only c-string function you should be using is strlen(), when someone else gives you a c string and you need to find out its length in order to start handling it safely.
Say you're writing a "kernel" function, be it an actual OS kernel or the request processing loop of a web-server, something like that. You have an interface (for compatibility purposes!) that takes C-strings, and you're interacting with an API that also takes C strings. You don't actually need to manipulate the string contents in this function, so you would normally pass the pointer straight through. However, for memory-management reasons the source string buffer will "go away" soon, so you have to do a byte-wise copy into a different buffer so that the contents can be preserved for later. Furthermore, for security (resource exhaustion) purposes, there's a configured limit on the size of the destination buffer, which has already been passed to the function by the request allocator, so you can't use strdup or strlen+malloc either. At this point your options are:

strlcpy (where available)
strlen + memcpy/mempcpy/whatever
snprintf
strncpy

I don't know, here strlcpy seems pretty ideal, and there's a well known idiom for checking for truncation. Drepper's arguments are that it's nonstandard, and makes it easy to ignore truncation errors. But he recommends, or did at one time, strlen+mempcpy which I argue is easier to screw up. snprintf (when invoked correctly) is fine but inefficient. It uses the same truncation-check idiom as strlcpy and is standard, but is "vulnerable" to format string exploits if used incorrectly. strncpy doesn't indicate whether truncation occurs and forces an external check, making it easy to skip entirely.

Now, in my own code I tend to use length-prefixed strings so the combination of memcpy and snprintf is sufficient. However, I get why the OpenBSD folks implemented strlcpy/strlcat. They do a lot of auditing and fixing of legacy code, including C-string handling code, and strlcpy/strlcat with a termination check is the most-straightforward way to make unsafe code safe.

I think the problem in this case is that folks comb through Linux (which, as a whole is newer code than what the OpenBSD audits were dealing with) looking for "strncpy issues" and blindly change up that code without motivation, getting it wrong in the process, and that's what Linus is complaining about.

ExcessBLarg! fucked around with this message at 18:13 on Sep 13, 2015

feedmegin
Jul 30, 2008

Plorkyeran posted:

Well yes, strncpy is designed for fixed-length buffers and strlcpy is designed for c strings. The fact that they operate on different data types isn't a problem with either one.

The fact that something designed to operate on fixed-length buffers and not strings begins with 'str' seems a bit of a problem.

loinburger
Jul 10, 2004
Sweet Sauce Jones
I was looking for a Java ScheduledThreadPoolExecutor implementation that included an exponential backoff policy. I found this
code:
An implementation that backs off exponentially based on the number of 
consecutive failed attempts stored in the {@link AsynchronousValidationRequest}.
It uses the following defaults:

no delay in case it was never tried or didn't fail so far
6 secs delay for one failed attempt (= {@link #getInitialExpiryInMillis()})
60 secs delay for two failed attempts
10 mins delay for three failed attempts
100 mins delay for four failed attempts
~16 hours delay for five failed attempts
24 hours delay for six or more failed attempts (= {@link #getMaxExpiryInMillis()})
For the life of me I can't think of anything that I'd ever want to retry that would use a 10x backoff multiplier with a max of 24 hours. "Why is this program hanging?" "Transient exception on the database, just give it another 10-100 minutes"

ExcessBLarg!
Sep 1, 2001

feedmegin posted:

The fact that something designed to operate on fixed-length buffers and not strings begins with 'str' seems a bit of a problem.
It's "str" because it takes (usually) a C-string as an input. It's also helpful to think of it as the much-less useful inverse function to strncmp.

Polio Vax Scene
Apr 5, 2009



This code is supposed to shorten inputstring to maxlength characters, by trimming off the end.

Supposed to.

code:
        protected static string StringMaxLength(string inputstring, int maxlength)
        {
            if (string.IsNullOrEmpty(inputstring)) { return string.Empty; }
            if ((inputstring.Length <= maxlength)) { return inputstring; }
            string outputstring = inputstring.Substring(1, (inputstring.Length > maxlength) ? maxlength : inputstring.Length - 1);
            return outputstring;
        }

senrath
Nov 4, 2009

Look Professor, a destruct switch!


Good old off by one errors.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
C# code:
// assume EST local timezone
var dst    = DateTime.Parse("2015-11-01T05:30:00Z");
var nonDst = DateTime.Parse("2015-11-01T06:30:00Z");
Console.WriteLine(dst);    // 11/1/2015 1:30:00 AM
Console.WriteLine(nonDst); // 11/1/2015 1:30:00 AM
Console.WriteLine(dst == nonDst); // true
In .NET, DateTime.Parse automatically converts UTC times into local time and loses information in the case of daylight savings time.

ExcessBLarg!
Sep 1, 2001
The first horror is that, that timestamp doesn't include a zone offset. I imagine that the result would still be amusing (and probably useless) if it did, though.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Bognar posted:

C# code:
// assume EST local timezone
var dst    = DateTime.Parse("2015-11-01T05:30:00Z");
var nonDst = DateTime.Parse("2015-11-01T06:30:00Z");
Console.WriteLine(dst);    // 11/1/2015 1:30:00 AM
Console.WriteLine(nonDst); // 11/1/2015 1:30:00 AM
Console.WriteLine(dst == nonDst); // true
In .NET, DateTime.Parse automatically converts UTC times into local time and loses information in the case of daylight savings time.

There's a reason DateTimeOffset exists and all new code should use it.

ExcessBLarg! posted:

The first horror is that, that timestamp doesn't include a zone offset. I imagine that the result would still be amusing (and probably useless) if it did, though.

The parsed string does, in fact, include a zone offset ("Z" means Zulu, or UTC, or GMT, or whatever other name we're using today).

The default ToString() on a DateTime doesn't include the time zone because timezone information is not included in the DateTime struct. Again, the DateTimeOffset struct was introduced to address this exact shortcoming, and all new code should avoid use of DateTime and only use DateTimeOffset.

Dessert Rose fucked around with this message at 22:27 on Sep 17, 2015

brap
Aug 23, 2004

Grimey Drawer
Aren't there problems with serialization of DateTimeOffsets?

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

fleshweasel posted:

Aren't there problems with serialization of DateTimeOffsets?

Some cursory searching suggests that XmlSerializer doesn't do it out of the box, but if you use a DataContractSerializer it's fine.

You're going to have to do some work either way: you have to send the timezone offset separately if you use a DateTime (or standardize on UTC), or you have to do a little bit of lifting to serialize a DTO properly.

Seems like a pretty poor oversight, though.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Dessert Rose posted:

The default ToString() on a DateTime doesn't include the time zone because timezone information is not included in the DateTime struct. Again, the DateTimeOffset struct was introduced to address this exact shortcoming, and all new code should avoid use of DateTime and only use DateTimeOffset.

I agree that DateTimeOffset should be used for capturing timezone information, but don't you think that parsing a time should result in the same representation of that time? If DateTime doesn't have timezone information, then parsing "5:30 AM" should result in 5:30 AM and not be converted based on whatever your local timezone is.

comedyblissoption
Mar 15, 2006

Avoid DateTime.

DateTimeOffset is better but still very ambiguous and can have many different meanings depending on context. This data type is often re-purposed to mean many different types of time-related concepts.

Noda seemingly tries to assign types and remove some ambiguity in handling time for some very common use cases. I looked through it and it looked cool but I haven't used it.
http://nodatime.org/

If you use the .Net stdlib time library someone will gently caress up somewhere eventually because rules for time are complicated and shoving this complication into a limited singular data type is a bad idea.

If you ask developers how many hours are in a day you'll get the wrong answer enough that it should worry you.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Bognar posted:

I agree that DateTimeOffset should be used for capturing timezone information, but don't you think that parsing a time should result in the same representation of that time? If DateTime doesn't have timezone information, then parsing "5:30 AM" should result in 5:30 AM and not be converted based on whatever your local timezone is.

So I dug deeper.

First, I would argue that there is a bug here, but it's simply in DateTime.operator==:
code:
Console.WriteLine(dst.IsDaylightSavingTime()); // true
Console.WriteLine(nonDst.IsDaylightSavingTime()); // false
Console.WriteLine(dst == nonDst); // true???
So there's that. But it does keep the information about DST in the struct, and converting it back to UTC results in sensible behavior:
code:
Console.WriteLine(dst.ToUniversalTime() == nonDst.ToUniversalTime()); // false
At this point, that bug is unfixable. Some code, somewhere, depends on this behavior, and will break in subtle and fun ways if it changes.

To address your argument that it shouldn't be converted to your local timezone, the interface of Parse() is more complicated than you're making it out to be, and if you bothered to read the documentation, you would find that you can get the behavior you want:
code:
var dst    = DateTime.Parse("2015-11-01T08:30:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
Console.WriteLine(dst);   // 11/1/2015 8:30:00 AM
DateTimeStyles has a bunch of different ways you can treat the string, including "always make it UTC if there's timezone information", "always make it local time", and "leave it the gently caress alone".

In summary, time is never as simple as developers want it to be. News at 11.

Dessert Rose fucked around with this message at 00:33 on Sep 18, 2015

ExcessBLarg!
Sep 1, 2001

Dessert Rose posted:

The default ToString() on a DateTime doesn't include the time zone because timezone information is not included in the DateTime struct.
I get that, and the common interpretation is that the time is in the local timezone of the machine. It would still be helpful, though, if the local timezone of the machine were included in the string.

Timestamps without time zones are incredibly annoying. Nearly every time I come across one, I end up wasting a bunch of time figuring out what zone it's in.

TheresaJayne
Jul 1, 2011

Bognar posted:

C# code:
// assume EST local timezone
var dst    = DateTime.Parse("2015-11-01T05:30:00Z");
var nonDst = DateTime.Parse("2015-11-01T06:30:00Z");
Console.WriteLine(dst);    // 11/1/2015 1:30:00 AM
Console.WriteLine(nonDst); // 11/1/2015 1:30:00 AM
Console.WriteLine(dst == nonDst); // true
In .NET, DateTime.Parse automatically converts UTC times into local time and loses information in the case of daylight savings time.

I know i am in a bit late but HUH???

how are you determining DST?

both of your datetimes are in GMT so the only way of telling the difference is to manually make it different.

shouldnt the strings be
2015-11-01T05:30:00 GMT
2015-11-01T05:30:00 BST

as one is GMT (Zulu) the other British Summer Time (dst)

MSDN says this

C# code:
// Display using date format information from hr-HR culture
DateTime thisDate = new DateTime(2008, 3, 15);
DateTimeFormatInfo fmt = (new CultureInfo("hr-HR")).DateTimeFormat;
Console.WriteLine(thisDate.ToString("d", fmt));      // Displays 15.3.2008

necrotic
Aug 2, 2005
I owe my brother big time for this!

TheresaJayne posted:

I know i am in a bit late but HUH???

how are you determining DST?


.NET is converting it from Zulu to his local time, and the second time is after DST ends in the Eastern timezone. Check out Desert Rose's longer post, the DST stuff is explained a little better.

Your last bit has only the fact that its a DateTime in common with the post you quoted so I don't know what thats all about.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

ExcessBLarg! posted:

It's "str" because it takes (usually) a C-string as an input. It's also helpful to think of it as the much-less useful inverse function to strncmp.

strncpy was designed for a field in a very specific data structure (d_name in dirent), and should never have become part of the general standard C library. Retconning its semantics as being kinda-for-strings, and pretending that it's ok to cpy a str but end up with something that isn't a str, is just whitewashing the fact that it was a mistake. (The API that exposed dirent to user space has long disappeared, happily.)

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



I'm evaluating this commercial Gantt chart library (Bryntum) which seems to be a pretty good library but has one critical flaw: the API documentation (the picky docs) is missing all of the methods that you need to use to actually use the charts.

It's bizarre, I go through the examples and see certain methods being used for things like adding new tasks to the chart so I consult the docs and nothing. Not under protected, private, deprecated, removed, the methods that you want to use are just not listed :confused:, plenty of other methods and properties you want to use are there -- just not the ones you need to use.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Dessert Rose posted:

First, I would argue that there is a bug here, but it's simply in DateTime.operator==:

So there's that. But it does keep the information about DST in the struct, and converting it back to UTC results in sensible behavior:

I found the same thing when I was playing around with it last night, so it's not as bad as I thought. The equality comparison is still unfortunate though.

Dessert Rose posted:

To address your argument that it shouldn't be converted to your local timezone, the interface of Parse() is more complicated than you're making it out to be, and if you bothered to read the documentation, you would find that you can get the behavior you want:

No need to be a dick about it. I'm well aware of the Parse overloads, but I still don't understand why Parse(string) defaults to converting to local time instead of just setting Kind to Utc.

Dessert Rose posted:

In summary, time is never as simple as developers want it to be. News at 11.

It's hard enough without strange API choices.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Working on calendaring software is non-stop horror. Just don't.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Bognar posted:

No need to be a dick about it. I'm well aware of the Parse overloads, but I still don't understand why Parse(string) defaults to converting to local time instead of just setting Kind to Utc.


Sorry, I just have low patience when people call things horrors without doing much research :shobon:

Think about this: if you have a time in any other timezone but your own or UTC, what should happen by default? It has to get converted to something, because DateTime doesn't have offset information. It can only be "local timezone" or "UTC", so it has to pick one. I would argue that, given the rest of the API defaults to local time, converting to local time is consistent with the semantics of DateTime. For example, DateTime.Now returns the local time; you need to call UtcNow if you want UTC, instead of Now returning UTC and LocalNow returning local time.

So what should happen if you call Parse with a UTC time? Should it suddenly decide to leave it alone? That would be pretty surprising, because in every other case Parse is converting to local time. If I test my app with a couple random timezones (but not UTC) and see that Parse is converting to local time, I'm going to be pretty mad and probably even post in this thread if it suddenly decides not to convert UTC times.

The single-parameter Parse is a convenience method. It's going to make some decisions for you that might not be the right ones, and that's totally fine! That's why you should always look at the other overloads and understand the decisions you can make, that the convenience method is making for you.

The lesson here is pay attention to the APIs you're calling. Especially with something as complicated as time, don't assume that the defaults fit your use case.

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!

Bognar posted:

No need to be a dick about it. I'm well aware of the Parse overloads, but I still don't understand why Parse(string) defaults to converting to local time instead of just setting Kind to Utc.
If you aren't being careful about timezones and whatnot, then you probably don't care about them, so you might as well just leave everything in local time.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Dessert Rose posted:

So what should happen if you call Parse with a UTC time? Should it suddenly decide to leave it alone? That would be pretty surprising, because in every other case Parse is converting to local time. If I test my app with a couple random timezones (but not UTC) and see that Parse is converting to local time, I'm going to be pretty mad and probably even post in this thread if it suddenly decides not to convert UTC times.

If the default was for Parse to always return a local time, I would probably agree with you here. However, when a timezone isn't specified it just has a DateTimeKind of Unspecified, which to me sounds appropriate. I think most of the other DateTime methods work in a similar way. To me, though, it seems like if you were supplied with a date where the specified time was UTC, the Kind should be UTC.

Really, though, I think the weirdness stems from DateTime attempting to have some limited notion of timezone, when it should have just left it the hell alone. I don't think this problem would have existed if DateTime just strictly parsed a Date and a Time and didn't bother with the kind.

Dessert Rose posted:

The single-parameter Parse is a convenience method. It's going to make some decisions for you that might not be the right ones, and that's totally fine! That's why you should always look at the other overloads and understand the decisions you can make, that the convenience method is making for you.

The lesson here is pay attention to the APIs you're calling. Especially with something as complicated as time, don't assume that the defaults fit your use case.

Totally agreed. I'm mostly just salty that I opened up an ancient project to fix a reported bug and found DateTime.Parse(string) being used *everywhere*.

EDIT: To actually answer your question...

Dessert Rose posted:

Think about this: if you have a time in any other timezone but your own or UTC, what should happen by default? It has to get converted to something, because DateTime doesn't have offset information.

DateTime should be used for dates and times in an unspecified timezone. If something with timezone information is being parsed into DateTime, that information should be lopped off entirely and the time shouldn't be converted to anything. That is, that's how I think it should be in my ideal world where DateTime wasn't already screwed up with Kind.

Bognar fucked around with this message at 19:22 on Sep 18, 2015

JawnV6
Jul 4, 2004

So hot ...
The duplicate hour messing up times that don't use it is fun. What happens when you try to specify a 1:30AM that's leapt forward over? Would 1:45 and 1:15 collapse to the same UTC time?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Looks like it'll happily represent DateTimes that didn't happen and adding/subtracting minutes doesn't jump out of the invalid range.

C# code:
var notime = new DateTime(2015,3,8,2,30,00,DateTimeKind.Local); //30 minutes past the beginning of DST
notime.Dump(); //2015-03-08 02:30:00
notime.AddMinutes(15).Dump(); //2015-03-08 02:45:00

ExcessBLarg!
Sep 1, 2001

Subjunctive posted:

strncpy was designed for a field in a very specific data structure (d_name in dirent), and should never have become part of the general standard C library.
That may well be the original reason the function was written, but dirent is hardly the only data type that embedded a fixed-length, non-terminated string. Such fixed-length records were common at the time. Even today, FAT continues to use 8.3 format filenames which are stored in a similar fixed length record (the only difference the convention of using 0x20 as a pad byte value instead of 0x0).

I suspect the reason strncpy was included in ANSI C is because, at that time, it was regularly used for it's original and intended purpose. How is that a mistake?

Subjunctive posted:

Retconning its semantics as being kinda-for-strings, and pretending that it's ok to cpy a str but end up with something that isn't a str, is just whitewashing the fact that it was a mistake.
Not trying to retcon anything. K&R (page 249) classifies it under "String Functions" and succinctly describes it's behavior:

The C Programming Language posted:

char *strncpy(s,ct,n): copy at most n characters of string ct to s; return s. Pad with '\0's if t has fewer than n characters.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Munkeymon posted:

Looks like it'll happily represent DateTimes that didn't happen and adding/subtracting minutes doesn't jump out of the invalid range.

C# code:
var notime = new DateTime(2015,3,8,2,30,00,DateTimeKind.Local); //30 minutes past the beginning of DST
notime.Dump(); //2015-03-08 02:30:00
notime.AddMinutes(15).Dump(); //2015-03-08 02:45:00

Interestingly, calling notime.ToUniversalTime() also works, but using TimeZoneInfo.ConvertTimeToUtc(notime, TimeZoneInfo.Local) throws an exception.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

ExcessBLarg! posted:

I suspect the reason strncpy was included in ANSI C is because, at that time, it was regularly used for it's original and intended purpose. How is that a mistake?

It was a mistake IMO to have a function that starts with str and doesn't always produce C strings, because all the other ones do and C strings are perilous enough to work with without that footgun sitting on the shelf. There is a false and dangerous symmetry between strcat/strcpy and strncat/strncpy. bufncpy or something would be better. You could even specify the terminator, so that it could actually be used with 0x20-padded FAT records, unlike strncpy.

(It's also the only str-function that writes to the target buffer beyond the extent of string-including-terminator, I think.)

Nippashish
Nov 2, 2005

Let me see you dance!
Speaking of strings, what the hell kind of string comparison function is this:

code:
/* compare two strings */

#ifdef KR_headers
integer s_cmp(a0, b0, la, lb) char *a0, *b0; ftnlen la, lb;
#else
integer s_cmp(char *a0, char *b0, ftnlen la, ftnlen lb)
#endif
{
register unsigned char *a, *aend, *b, *bend;
a = (unsigned char *)a0;
b = (unsigned char *)b0;
aend = a + la;
bend = b + lb;

if(la <= lb)
	{
	while(a < aend)
		if(*a != *b)
			return( *a - *b );
		else
			{ ++a; ++b; }

	while(b < bend)
		if(*b != ' ')
			return( ' ' - *b );
		else	++b;
	}

else
	{
	while(b < bend)
		if(*a == *b)
			{ ++a; ++b; }
		else
			return( *a - *b );
	while(a < aend)
		if(*a != ' ')
			return(*a - ' ');
		else	++a;
	}
return(0);
}

fritz
Jul 26, 2003

Nippashish posted:

Speaking of strings, what the hell kind of string comparison function is this:


A regrettable one.

ExcessBLarg!
Sep 1, 2001

Subjunctive posted:

It was a mistake IMO to have a function that starts with str and doesn't always produce C strings,
So, the strn-prefix functions all "do something" with C strings and fixed-length strings. Perhaps the "strn" prefix was poor in retrospect. Honestly I don't think there was that much confusion until folks started misapplying them as "safe" string functions which wasn't their intention. Even that would've been less of a problem if GNU libc had just implemented strlcpy/strlcat so folks wouldn't have sought the misleading alternatives.

I don't think they're bad functions, aside from strncat which is difficult to use safely--enough so that it's equivalently bad to strcat for me. strncpy and strncmp though are still useful when having to marshal to fixed-length string records. If you object to the "strn" prefix, fair enough, but I don't think the presence of those functions in the standard library is otherwise unreasonable, especially compared much greater warts in the library (gets, strtok, all the non-reentrant ones, etc.).

Adbot
ADBOT LOVES YOU

Soricidus
Oct 21, 2010
freedom-hating statist shill
the problem is that people are using the C standard library string functions ityool 2015. this is bad and they should stop doing so except where absolutely necessary. it really doesn't matter what the functions were designed for or how safe your "safe strcpy replacement" is. C strings are a mess that can't be fixed. it's time to put them down.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply