Live data from Hacker News

Improvements to static analysis in GCC 14

developers.redhat.com

91–100 of 147 posts

Re: Improvements to static analysis in GCC 14

#91

Earlier quoted context omitted.

It's not possible to use it safely unless you know that the source string fits in the destination buffer. Every strncpy must be followed by `dst[sizeof dst - 1] = 0`, and even if you do that you still have no idea if you truncated the source string, so you have to put in a further check. strncpy (dst, src, (sizeof dst) - 1); dst[(sizeof dst) - 1] = 0; int truncated = strlen (dst) - strlen (src); Without the extra two…

if you really want to use standard C string functions, use instead: int ret = snprintf(dst, sizeof dst, "%s", src); if (ret >= n || ret or as a function: bool ya_strcpy(const char* s, char* d, size_t n) { int cp = snprintf(d, n, "%s", s); bool ok = cp >= 0 && cp

except no one does that return code check and worse they often use the return code to advance a pointer in concatenated strings

Re: Improvements to static analysis in GCC 14

#92

Earlier quoted context omitted.

[flagged]

I’m talking about C++. You wrote that Clang already had friendly error messages. While they were less unfriendly than GCC, calling them friendly is a stretch. Rust having traits instead of templates is a big ergonomic improvement in that area.

Funnily enough, trait bounds are still a big pain in the neck to provide good diagnostics for because of the amount of things that need to be tracked that are cross cutting across stages of the compiler that under normal operation don't need to talk to each other. They got better in 2018, as async/await put them even more front and center and focused some attention on them, and a lot of work for keeping additional metadata around was added since then (search the codebase for enum ObligationCauseCode if you're curious) to improve them. Now with the new "next" trait solver they have a chance to get even better.

It still easier than providing good diagnostics for template errors though :) (althought I'm convinced that if addressing those errors was high priority, common cases of template instantiations could be modeled internally in the same way as traits purely for diagnostics and materially improve the situation — I understand why it hasn't happened, it is hard and not obviously important).

Re: Improvements to static analysis in GCC 14

#93
post #44

Earlier quoted context omitted.

Speaking of strlcpy, Linus has some colorful opinions on it: > Note that we have so few 'strlcpy()' calls that we really should remove that horrid horrid interface. It's a buggy piece of sh*t. 'strlcpy()' is fundamentally unsafe BY DESIGN if you don't trust the source string - which is one of the alleged reasons to use it. --Linus Maybe strscpy is finally the one true fixed design to fix them all. Personally I think…

> the real solution is obvious If it were obvious it would have been done already. Witness the many variants that try to make it better but don't. > using proper string buffer types with length and capacity Which you then can't pass to any other library. String management is very easy to solve within the boundaries of your own code. But you'll need to interact with existing code as well.

For me the "real" solution looks something like this:

    ssize_t strxcpy(char* restrict dst, const char* restrict src, ssize_t len)
Strxcpy copies the string from src to dst. The len parameter is the number of bytes available in the dst buffer. The dst buffer is always terminated with a null byte, so the maximum length of string that can be copied into it is len - 1. strxcpy returns the number of characters copied on success, but can return the following negative values:

    E_INVALID_PARAMETER: Ether dst or src are NULL or len 
strxcat would work similarly. I have not decided if the return value should include the terminating null or not.

Re: Improvements to static analysis in GCC 14

#94
post #81
post #48

Earlier quoted context omitted.

I have had the exact opposite experience: clang constantly gives me much better error messages than GCC, implementations of some warnings or errors catch more cases, and clang-tidy is able to do much better static analysis.

"Copilot explain this error" has made this whole discussion irrelevant for me.

An issue is immediacy: problems are better the earlier they are pointed out (why online errors are better than compile errorswl, which are better than CI errors, which are runtime errors). Having to copy paste an error adds a layer of indirection that gets in the way of the flow.

Another is reproducibility and accuracy: LLMs have a tendency to confidently state things that are wrong, and to say different things to different people, the compiler has the advantage of being deterministic and generally have better understanding of what's going on to produce correct suggestions (although we still have cases of incorrect assumptions producing invalid suggestions, I believe we have a good track record there).

If those tools help you, more power to you, but I fear their use by inexperienced rustaceans being misled (an expert can identify when the bot is wrong, a novice might just end up questioning their sanity).

Side note: the more I write the more I realize that the same concerns I have with LLMs also apply to the compiler in some way and am trying to bridge that cognitive dissonance. I'm guessing that the reproducibility argument, ensuring the same good error triggers for everyone that makes the same mistake and the lack of human curation, are the thing that makes me uneasy about LLMs for teaching languages.

Re: Improvements to static analysis in GCC 14

#95
post #44

Earlier quoted context omitted.

> the real solution is obvious If it were obvious it would have been done already. Witness the many variants that try to make it better but don't. > using proper string buffer types with length and capacity Which you then can't pass to any other library. String management is very easy to solve within the boundaries of your own code. But you'll need to interact with existing code as well.

For me the "real" solution looks something like this: ssize_t strxcpy(char* restrict dst, const char* restrict src, ssize_t len) Strxcpy copies the string from src to dst. The len parameter is the number of bytes available in the dst buffer. The dst buffer is always terminated with a null byte, so the maximum length of string that can be copied into it is len - 1. strxcpy returns the number of characters copied on su…

How is this useful though? I mean yes, it is useful in avoiding the buffer overruns. But that's not the only consideration, you also want code that handles data correctly. This just truncates at buffer size so data is lost.

So, if you want the code to work correctly, you need to either check the return code and reallocate dst and call the copy again. But if you're going to do that might as well check src len and allocate dst correctly before calling it so it never fails. But if you're already doing that, you can call strcpy just fine and never have a problem.

Re: Improvements to static analysis in GCC 14

#96
post #71

Earlier quoted context omitted.

We all agree that you shouldn't write bad code. Not using goto, not using any language construct. But when unbridled gotos were the only tool in the toolbox, bad code was an inevitability in a codebase of any meaningful size. Not even the best programmer was immune. This is what the "Go to statement considered harmful" paper was about. It was written in 1968. We listened. We created languages that addressed the conce…

In 1968 they had better languages and programmers were still using goto for control in them despite better options.

Of course. The ideas presented in said paper went back at least a decade prior, but languages were still showing up with unbridled gotos despite that. But that has changed in the meantime. What language are you or anyone you know using today that still has an unbridled goto statement?

Re: Improvements to static analysis in GCC 14

#97

Earlier quoted context omitted.

if you really want to use standard C string functions, use instead: int ret = snprintf(dst, sizeof dst, "%s", src); if (ret >= n || ret or as a function: bool ya_strcpy(const char* s, char* d, size_t n) { int cp = snprintf(d, n, "%s", s); bool ok = cp >= 0 && cp

snprintf only returns negative if an "encoding error" occurs, which has to do with multi-byte characters. I think for that to possibly happen, you have to be in a locale with some character encoding in effect and snprintf is asked to print some multi-byte sequence that is invalid for that encoding. Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen.

> Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen.

Of all the footguns in a hosted C implementation, I believe setlocale (and locale in general) is so broken that even compilers and library developers can't workaround it to make it safe.

The only other unfixable C-standard footgun that comes close, I think, are the environment-reading-and-writing functions, but at least with those, worst-case is leaking a negligible amount of memory in normal usage, or using an old value even when a newer one is available.

Re: Improvements to static analysis in GCC 14

#98

Earlier quoted context omitted.

snprintf only returns negative if an "encoding error" occurs, which has to do with multi-byte characters. I think for that to possibly happen, you have to be in a locale with some character encoding in effect and snprintf is asked to print some multi-byte sequence that is invalid for that encoding. Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen.

> Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen. Of all the footguns in a hosted C implementation, I believe setlocale (and locale in general) is so broken that even compilers and library developers can't workaround it to make it safe. The only other unfixable C-standard footgun that comes close, I think, are the environment-reading-and-writing f…

I see that in Glibc, snprintf goes to the same general _IO_vsprintf function, which has various ominous -1 returns.

I don't think I see anything that looks like the detection of a conversion error, but rather other reasons. I would have to follow the code in detail to convince myself that glibc's snprintf cannot return -1 under some obscure conditions.

Defending against that value is probably wise.

As far as C locale goes, come on, the design was basically cemented in more or less its current form in 1989 ANSI C. What the hell did anyone know about internationalizing applications in 1989.

Re: Improvements to static analysis in GCC 14

#99
post #57
post #54

Earlier quoted context omitted.

For signed overflow I use -fsanitize=signed-integer-overflow .

Good. I wonder how many people do and also if their compilers support it. (One would hope so, of course. I assume clang and GCC do.) ... but the question is really what you ship to production. Btw, possible signed overflow was just an example of things people do not want warnings for . OOB is far more dangerous, obviously... and the cost for sanitizer in that case is HUGE... and it doesn't actually catch all cases AF…

For OOB you can enable bound checking in the C++ standard library. That's relatively cheap. Of course it won't help with C raw pointers and C array.
Post reply on HN