Tell HN: C Experts Panel – Ask us anything about C
881–890 of 978 posts
Re: Tell HN: C Experts Panel – Ask us anything about C
#882Earlier quoted context omitted.
There are "projects" underway to clean up the spec where it's viewed as either buggy, inconsistent, or underspecified. The atomics and threads sections are a coupled of example. There are efforts to define the behavior in cases where implementations have converged or died out (e.g., twos complement, shifting into the sign bit). There have been no proposals to add new array types and it doesn't seem likely at the core…
> no such feature has emerged in practice Arrays with length constantly emerge among C users and libraries. They are just all incompatible because without standardization there is no convergence.
Re: Tell HN: C Experts Panel – Ask us anything about C
#8831. How likely are named constants of any types to be included in C2x? I'm referring to the idea of making register const values be usable in constant expressions. 2. Is there, or was there ever a proposal to make struct types without a tag be structurally typed? This would not break backwards compatibility as far as I can see, and would make these types much more useful as ad-hoc bags of data. Small example: struct {…
(disclaimer: also a WG14 member) 1. I want this too. 2. Here is my proposal: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2366.pdf 3. Yes, variadic functions should be improved.
I think the authors of C89 most likely thought that principle was sufficiently obvious that there was no need to expressly state it. Were it not for the Standard's rule forbidding it, an implementation might plausibly have ignored the possibility of an `int` being accessed via an `unsigned`, but I don't think the authors of the Standard imagined that a non-obtuse compiler writer wouldn't allow for the possibility that something like:
void inc_float_bits(float *f)
{
((unsigned*)f)+=1;
}
might affect the stored value of a `float`.The present rules, as written, have absurd corner cases. Given something like:
union U { float f[2]; unsigned ui[2]; } uu;
the Standard would, so far as I can tell, treat as identical the functions test1, test2, and test3 below: float test1(int i, int j)
{
uu.f[i] = 1.0f;
uu.ui[j] += 1;
return uu.f[i];
}
float test2(int i, int j)
{
*(uu.f+i) = 1.0f;
*(uu.ui+j) += 1;
return *(uu.f+i);
}
float evil(unsigned *ui, float *f)
{ *f = 1.0f; *ui += 1; return *f; }
int test2(int i, int j)
{
evil(uu.f+i, uu.ui+j);
}
If a dereferenced pointer to union member type isn't allowed to access the union, the first example would be UB regardless of i and j, but that would imply that non-character arrays within unions are meaningless. If such pointers are allowed to access union objects, then test2 (and the evil function within it) would have defined behavior even when i and j are both zero.BTW, I think any quality compiler should recognize the possiblity of type punning in the first two, though the Standard doesn't actually require either. Neither clang or gcc, however, recognizes the possibility of type punning in the second even though the behavior of the [] operators in the first are defined* as equivalent to the second.
Re: Tell HN: C Experts Panel – Ask us anything about C
#884Earlier quoted context omitted.
The very few times I've ever put in a check like that, I always do something like i < MAX_INT - 5 just to be sure, because I'm never confident that I intuitively understand off-by-one errors.
Same here. But I instead run a loop over a range around MAX_INT (or wherever the issue is) and print the result, so I know I'm doing what I think I'm doing. Exhaustive testing is quick, with a computer!
Re: Tell HN: C Experts Panel – Ask us anything about C
#885Earlier quoted context omitted.
> CHAR_BIT needs to be 8. Why?
Everything breaks if it isn't. I was on an OS development team in the 1990s. We were using the SHARC DSP, which was naturally a word-addressed chip. Endianness didn't exist in hardware, since everything was whatever size (32, 40, or 48 bits) you had on the other end of the bus. Adding 1 to a hardware pointer would move by 1 bus width. The chip vendor thought that CHAR_BIT could be 32 and sizeof(long) could be 1. We c…
Re: Tell HN: C Experts Panel – Ask us anything about C
#886"m" is the same as "w", but does not truncate the file. In POSIX terms, it doesn't add O_TRUNC to the flags.
There is "r+", of course; but "r+" requires that the file exists already. In POSIX terms, "r+" does not include the O_CREAT flag.
fopen("foo", "m") creates the file if it does not exist, and opens it for writing. The stream is positioned at the beginning of the file without truncating it.
We can sort of emulate it with fopen("foo", "a"), then fclose, then open with "r+".
Re: Tell HN: C Experts Panel – Ask us anything about C
#887Many of your remaining questions have devolved into "When will I see my favorite feature xyz appear in the C Standard?" The answer in most cases is "that depends on how long it takes you to submit a proposal". Take a look at http://www.open-std.org/jtc1/sc22/wg14/www/wg14_document_log... for previous proposals and review the minutes to see which proposals have been adopted. In general, the committee is not going to a…
Thanks to one and all for this AMA! The massive number of comments testifies to the continuing interest in C, and I think we're all grateful to all of you for your expertise, your patience, and your even-handed responses.
1. define a highly-extensible abstraction model, which implementations intended for various purposes should be expected to extend to suit those purpose, or
2. define an abstraction model which is sufficiently complete that programs can do everything that would need to be done, without need for extensions?
Reading the C89 and C99 Rationale documents, it's clear that those standards were intended to meet the former purpose. The way some compilers treat "Undefined Behavior", however, suggests that the maintainers view the Standard as aimed toward the latter purpose.
During the 1980s and 1990s, it was generally cheaper and easier for implementations to extend the Standard's abstraction model by specifying that many actions would be processed "in a documented fashion characteristic of the environment" than it would have been to do anything else, so there was no need to worry about whether the Standard allowed programmers to specify when such behavior was required. That no longer holds true, however.
While it would be reasonable to deprecate code which relies upon such treatment without explicitly demanding it, such deprecation would only make sense if there were a means of demanding such treatment when required. For the Committee to provide such means, however, it would have to reach a consensus as to the purposes for which the Standard's abstraction model is meant to be suitable. Are you aware of any such consensus?
Re: Tell HN: C Experts Panel – Ask us anything about C
#888Re: Tell HN: C Experts Panel – Ask us anything about C
#889Earlier quoted context omitted.
There are rules and requirements documented in the spec, and there are de-facto rules and requirements that programs expect. Not only that, but when they do exploit these rules, often the code generated is obviously incorrect, and could have been flagged at compile time. Right now, it seems like compiler vendors are playing a game of chicken with their users.
I think the issue is that many of these "obviously incorrect" things are not obvious at the level that the optimizations are taking place. Perhaps it would be worth considering adding higher-level passes in the compiler that can detect these kinds of surprising changes and warn about them.
Hmm...then it's up to the optimisers to up their game.
Optimisation is supposed to be behaviour-preserving. Arguing that almost all real-world programs invoke UB and therefore don't have well-defined behaviour (by the standard as currently interpreted) is a bit of a cop-out.
Re: Tell HN: C Experts Panel – Ask us anything about C
#890Earlier quoted context omitted.
Sure, but theres a vast space between the C and C++ approaches. You don't have to say yes to everything to say yes to a few things. I would suggest that better arrays are an example of something that pretty much everybody wants.
But if you want better arrays you want operator overload to be able to use these arrays as 1st class citizens without having to use array_get(arr, 3), array_len(arr), array_concatenate(arr1, arr2) etc... You want to be able to write "arr[3]", "arr.len()", "arr1 += arr2" etc... To implement operator overload you might need to add the concept of references. If you want your arrays type-safe you'll need dark macro magic…
I don't think that's true at all.
1. "arr[3]" syntax can just be part of the language.
2. For length, we already have the "sizeof()" syntax, although admittedly it is a compile-time construct and expanding it to runtime could be confusing. I am ok with using a standard psuedo-function for array-len and would absolutely prefer it to syntax treating first-class arrays as virtual structs with virtual 'len' members.
3. I don't think any C practitioner wants "arr1 += arr2" style magic.
So I don't buy that there is a need for operator overload; the rest of your claims that this is basically an ask for C++ follow baselessly from that premise.