Live data from Hacker News

Tell HN: C Experts Panel – Ask us anything about C

news.ycombinator.com

631–640 of 978 posts

Re: Tell HN: C Experts Panel – Ask us anything about C

#631

Earlier quoted context omitted.

I can't imagine it will ever be changed, since this would be a breaking change to the language.

I disagree that this would be a "breaking" change as many people have already resorted to using extra () and such a change might actually may "fix" broken code which makes the reasonable assumption that things like == have a higher-order. https://ericlippert.com/2020/02/27/hundred-year-mistakes/ int x = 0, y = 1, z = 0; int r = (x & y) == z; // 1 int s = x & (y == z); // 0 int t = x & y == z; // 0 UGH

If you're using parentheses, as has been recommended for decades, there is no problem. Otherwise, it is likely that such a change would adversely impact previously working code. There just isn't a pressing need to change it.

Re: Tell HN: C Experts Panel – Ask us anything about C

#632

The standard string library is still pretty bad. This would have been a much better addition for safe strcpy. Safe strcpy char *stecpy(char *d, const char *s, const char *e) { while (d Existing solutions are still error-prone, requiring continual recalculation of buffer len after each use in a long sequence, when the only thing that matters is where the buffer ends, which is effectively a constant across multiple cal…

What's wrong with: *p += sprintf(*p, "hello"); *p += sprintf(*p, "world");

Perhaps you meant snprintf. But snprintf can fail on allocation failure, fail if the buffer size is > INT_MAX, and in general isn't very light weight--last time I checked glibc, snprintf was a thin wrapper around the printf machinery and is not for the faint of heart--e.g. initializing a proxy FILE object, lots of malloc interspersed with attempts to avoid malloc by using alloca.

It can also fail on bad format specifiers--not directly irrelevant here except that it forces snprintf to have a signed return value, and mixing signed (the return value) and unsigned (the size limit parameter) types is usually bad hygiene, especially in interfaces intended to obviate buffer overflows.

Re: Tell HN: C Experts Panel – Ask us anything about C

#633
post #621

Earlier quoted context omitted.

Arrays are pointers. If they aren't pointers then you need to copy the data when you are giving an array as a function parameter. that's a lot slower. Being able to prepare an set of data in an array and then giving a pointer to a function is very useful. You could add a second type of array on top of what you have in C that includes more stuff, but if that's what you want you can implement that yourself with a struc…

An array is not a pointer. These are completely different data types. For example, you can't apply pointer arithmetic to arrays without casting them to pointers.

they are accessed using pointer arithmetic, if you wanted them to contain length data, you would need a different access pattern. I think one of the great features of C is that it doesn't do anything under the hood, its all explicit. If you want to bounds check, then do it.

Re: Tell HN: C Experts Panel – Ask us anything about C

#634
post #621

Earlier quoted context omitted.

An array is not a pointer. These are completely different data types. For example, you can't apply pointer arithmetic to arrays without casting them to pointers.

they are accessed using pointer arithmetic, if you wanted them to contain length data, you would need a different access pattern. I think one of the great features of C is that it doesn't do anything under the hood, its all explicit. If you want to bounds check, then do it.

> they are accessed using pointer arithmetic

Not always. Consider:

    int a[3];
    a[1] = 2;
This is not using pointer arithmetic. Dump the generated code if you don't believe me :-)

Re: Tell HN: C Experts Panel – Ask us anything about C

#635

The standard string library is still pretty bad. This would have been a much better addition for safe strcpy. Safe strcpy char *stecpy(char *d, const char *s, const char *e) { while (d Existing solutions are still error-prone, requiring continual recalculation of buffer len after each use in a long sequence, when the only thing that matters is where the buffer ends, which is effectively a constant across multiple cal…

What's wrong with: *p += sprintf(*p, "hello"); *p += sprintf(*p, "world");

It looks like you'd be dereferencing the pointer p, but you'd also need to make sure that what p points to has enough memory.

Re: Tell HN: C Experts Panel – Ask us anything about C

#636

Earlier quoted context omitted.

I'm not sure what your requirement is. Usually things work out if you're careful not to assume any specific value for alignment etc. It may mean a few unused bytes here and there, but keeping things simple and portable often pays off.

Being able to know your alignments is VERY important for a lot of network implementations. They are all defined by the ABIs, but its very annoying that the standard keeps thinking that alignment is unknowable, when in fact its impossible to implement a ABI without defining it. One of the reasons I stick to C89.

Note that the ABIs cover endianness as well as value range and/or object widths. In general, one needs to have explicit marshaling and unmarshaling functions to map from network octet array and C internal data representation. Failure to get this right is (or used to be) a common bug for code developed and tested on too few architectures.

Re: Tell HN: C Experts Panel – Ask us anything about C

#637

Does the following code fragment cause undefined behaviour? unsigned int x; x -= x; There's a lengthy StackOverflow thread where various C language-lawyers disagree on what the spec has to say about trap values, and under what circumstances reading an uninitialised variable causes UB. I'd appreciate an authoritative answer. Thanks for dropping by on HN! https://stackoverflow.com/q/11962457/

This example is clearly UB. You could argue that it suddenly becomes less UB if you take the address of x: unsigned int x; &x; x -= x; I'm not sure if this will add anything to the discussion on SO, but if you allow programs to do this, then after applying modern optimizing C compilers, you may end with multiplications by 2 that produce odd results, or uninitialized char variables that contain 500: http://blog.frama-…

Interesting link, thanks. So then:

* Under C90, reading an uninitialized local was explicitly listed as UB.

* Under C99, if you weren't using a character type, it was still essentially UB, by way of trap values. (I don't think the particulars of the target hardware platform are relevant.)

* C11 reintroduced UB even for some cases involving character types. We were already invoking UB under C99, so we know we're still invoking UB under C11.

> You could argue that it suddenly becomes less UB if you take the address of x

I don't think so. As we're not using a character type, I don't think taking its address would change anything. This aligns with what msebor said.

Lastly, from the article:

    > No, GCC is still acting as if j *= 2; was undefined.
I think GCC's behaviour is legal here. The target platform may have no trap values, but I don't see that GCC is prohibited from behaving as if there are. It would be legal (albeit bizarre) for it to generate code for a completely different ISA, and to bundle an emulator. If the spec says you've opened the door to UB, then unless your compiler documentation says otherwise, it's permitted to generate code that goes haywire, no?

Re: Tell HN: C Experts Panel – Ask us anything about C

#638

What does the presence or absence of __STDC_ISO_10646__ indicate exactly? I found this part of the C99 spec obscure. For instance, the macOS clang environment does not define this symbol. Is their implementation of wchar_t or lacking some aspect of Unicode support?

If that macro is defined, then wchar_t is able to represent every character from the Unicode required character set with the same value as the short code for that character. Which version of Unicode is supported is determined by the date value the macro expands to.

Clang defines that macro for some targets (like the Cloud ABI target), but not others. I'm not certain why the macro is not defined for macOS though (it might be worth a bug report to LLVM, as this could be a simple oversight).

Re: Tell HN: C Experts Panel – Ask us anything about C

#639
post #621

Earlier quoted context omitted.

An array is not a pointer. These are completely different data types. For example, you can't apply pointer arithmetic to arrays without casting them to pointers.

That's right. They are converted to pointers when passed to a function, even if the function declares the parameter as an array.

They're not converted but can be implicitly casted to pointer types.

Re: Tell HN: C Experts Panel – Ask us anything about C

#640

As a C newbie, will there ever be "safe" C, i.e. no undefined behavior and help with writing code that has less memory related crashes/bugs? For comparison, Rust has the `unsafe { }' block which lets you mark regions of code as being able to do funky stuff. Could we get the opposite for C, i.e. `safe { }' and for an entire file, `#pragma safe'? I have a love-hate relationship with C - I like it for small projects, bu…

I'm pretty happy with C as it is, but I will admit to being surprised that a "minimalistic Rust" hasn't risen to prominence. I guess what I mean by that is a language that has Rust's hyperactive, strongly opinionated compiler, borrow checker, no NULL, immutable by default, etc, but in a language that is no more syntactically ambitious that C89. I would be way more into a language like that than Rust. A language that…

I think it's going to arrive, but some time is needed to see what works in Rust or not. D is going this way as well, so should provide another data point.
Post reply on HN