rseacord
rseacord on Hacker News
Please submit a proposal.
I've heard this comment more than once. What we are trying to accomplish is to collocate the resource acquisition code with the acquisition release code. This does mean that the release code is removed when where the release occurs (for example, at every location a function returns.
However, this is not without precedence in C. For example, just look at the for loop:
for (clause1; expression2; expression3)
statement
expression3 is executed after statement.
Yes, you are correct and there wasn't much support for capturing values so we would probably only support capture by reference and wait to see if C solves this problem in general by introducing lambdas.
Based on feedback from the committee, I think it's very unlikely a dynamic approach will be used. The static only affects the for loop in terms of whether the deferred statements are run once or for each iteration of the loop, and the only real world use of this I've found so far involves allocating and deallocating resources within each loop iteration which would be supported by the static approach.
Based on committee discussion, I think it is unlikely we will attempt to capture the values. The capture will most likely be done by reference.
This case of the defer in the loop is frequently cited, probably because it is a problematic case. However, I looked at a lot of real code and the only case I found of resources being allocated in a loop they were allocated at the beginning of the loop and deallocated at the end. Another option we are considering is to use the scope for the guarded block. In this case, deferred statements would be executed at the end of each iteration of the for loop which would be ideal for this sort of code. For example, you could rewrite this function using defer:
https://github.com/openssl/openssl/blob/a829b735b645516041b5...
like this:
for (;;) {
raw = 0;
ptype = 0;
i = PEM_read_bio(bp, &name, &header, &data, &len);
defer {
OPENSSL_free(name);
name = NULL;
OPENSSL_free(header);
header = NULL;
OPENSSL_free(data);
data = NULL;
}
...
} else {
/* unknown */
}
} // end for loop, run deferred statements
Should work provided your wchar_t type is at least 21-bits wide.
I don't really see C going anywhere. It's not going away, and it's not going to evolve into Java. It's going to remain especially useful for memory constrained and performance critical applications such as IoT and embedded.
For (3) mandatory warnings the closest thing is probably ISO/IEC TS 17961:2013. The purpose of ISO/IEC TS 17961 is to establish a baseline set of requirements for analyzers, including static analysis tools and C language compilers, to be applied by vendors that wish to diagnose insecure code beyond the requirements of the language standard. All rules are meant to be enforceable by static analysis. The criterion for selecting these rules is that analyzers that implement these rules must be able to effectively discover secure coding errors without generating excessive false positives.
Many 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 adopt proposals for which there is insufficient existing practice or haven't been fully thought out. There are cases where people have come to a single meeting with a well-considered proposal that was adopted into the C Standard. I wrote about one such case here:
https://www.linkedin.com/pulse/alignment-requirements-memory... Alternatively, you can approach someone on the committee and ask us to champion a proposal for you. It is likely that we'll agree or at least provide you with feedback on your proposal.
For (2) I guess it depends. Annex K is obviously already a part of the standard so it depends on the implementation. There is a push to eliminate Annex K altogether from the C Standard. If this push fails, it may be the case that more libraries will add support for this optional feature of the language. In the meanwhile, there is the Open Watcom compiler implementation [1], the Safe C Library [2], and Slibc [3].
[1] Watcom C Library Reference Version 1.8. Open Watcom. 2008. ftp://ftp.openwatcom.org/manuals/current/clib.pdf
[2] Safe C Library — A full implementation of Annex K https://github.com/rurban/safeclib/
[3] slibc https://code.google.com/archive/p/slibc/
Going to try to answer these separately. For (1) if you mean strings that are primitive types my guess is never. When had an hour discussion on this topic at a London meeting where we were discussing new features for C11 and my take away was that this would never happen because it would require a significant change to the memory model for the language.
So I spend a possibly unreasonable amount of time and page space discussing VLAs in the Effective C book. I understand there are some problems with them, but for what it is worth, I really like the feature, particularly when used in function prototype scope.
Microsoft originally implemented the Annex K Bounds checked interfaces (e.g., the *_s functions) back in the 1990s in response to well-publicized vulnerabilities. They proposed standardization to the C Standards committee. The committee made many changes to the proposal, possibly going too far away from the original implementation. During this time, I would say that Microsoft was very differential to the wishes of the committee.
By the time the ISO/IEC TR 24731-1:2007 was released, and then later Annex K added to the C Standard, Microsoft had to decide if they wanted to change the interfaces to conform to the changed standard and re-implement their code bases. They presumably decided that they did not, which I think is a defensible decision.
As to unergonomic, examples please?
I think a lot of these dudes are retired. A lot of good C people like P.J. Plauger, John Benito, and Clark Nelson have all retired recently. Anyway, they are all invited back. As an incentive, we typically have free coffee and snacks at most of the meetings. :)
Some example of hardware variation (since you mentioned shifting and overflow):
- signed integer overflow or division by zero occurs, a division instruction traps on x86, while it silently produces an undefined result on PowerPC
- left-shifting a 32-bit one by 32 bits yields 0 on ARM and PowerPC, but 1 on x86;
- left-shifting a 32-bit one by 64 bits yields 0 on ARM, but 1 on x86 and PowerPC
I would say that there is a lot of concern in the committee about how compilers are optimizing based on pointer providence. There has been a study group looking at this. It now appears that they are likely to publish their proposal as a Technical Report.
Yes, we have discussed adding this feature at scope level. A not entirely serious proposal was to implement it as follows:
#define DEFER(a, b, c) \
for (bool _flag = true; _flag; _flag = false) \
for (a; _flag && (b); c, _flag = false)
int fun() {
DEFER(FILE *f1 = fopen(...), (NULL != f1), mfclose(f1)) {
DEFER(FILE *f2 = fopen(...), (NULL != f2), mfclose(f2)) {
DEFER(FILE *f3 = fopen(...), (NULL != f3), mfclose(f3)) {
... do something ...
}
}
}
}
We are also looking at the attribute cleanup. Sounds like you should be involved in developing this proposal?
I would say that the committee does pay attention to hardware variations, even when there are no examples of existing hardware that implement a feature (for example, a trap representation for integers other than _Bool). Some of the thinking is that "if it was ever implemented in hardware, it could be again). I'm not crazy about this thinking, and I largely think that language features for which there are no existing hardware implementations should be eliminated and then brought back if needed. However, the C Committee is much smaller than the C++ committee so there is a labor shortage. More people getting involved would certainly help.
We have dropped support for sign and magnitude and one's complement architectures from C2x (a decision Doug Gwyn does not agree with). There was some concern that Unisys may still use a one's complement architecture, but that this may only be in emulation nowadays.
It has not. The C Committee has taken two votes on this, and in each case, the committee has been equally divided. Without a consensus to change the standard, the status quo wins.
Sounds like you don't care for Annex K. What don't you like about it?
I don't know of any plans to add semantics for divide-by-zero of dereferencing a null pointer. I'm guessing this is not viable because there is no agreed upon semantics among different implementations.
Making C friendlier is always a good idea, and I think the committee is (slowly) working towards this goal. I would have to examine these papers by John Regehr in more detail. Looking quickly at his proposals I can see why there he couldn't find consensus for these ideas as some of them do appear controversial.
An example of a friendly dialect of C is always is C0 (C-naught) from CMU. I don't think I'm exaggerating when I say that this language has not "caught on".
Sounds like a good use of standardization. If there is existing implementation practice, please go ahead and submit a proposal. I would be happy to champion such a proposal if you can't attend in person.
I spent the early part of my career bragging about how many programming languages I knew, and the later part of my career complaining about how I don't know any of them well enough.
Well, there are number of problems with this proposal. For example, if your implementation defines int as a 16-bit type (which is permitted for by the standard) and you pass an int32_t, the value you pass maybe truncated if it is outside of the range of the narrower type. When programming, it is best to match the type of the API of the function you are calling for portability.
This depends a bunch on what your goals are. There are no specially named files, so looking for a particular filename is not particularly useful. It is sometimes informative to find the file containing the main, but not always.
My job at NCC Group involves a lot of code reviews, so frequently the files that are of interest to me are the ones that contain the most defects. I typically identify these by compiling with compiler warnings turned up and warning suppression turned down. I'll frequently also make use of static and dynamic analysis, including the GCC and Clang sanitizers.
There is always a chance. We would need to see a proposal based on experience with an existing implementation.
I'll pass this on to the publisher....