Earlier quoted context omitted.
I think we are always looking at ways to "clean up C" but that this has to be done very carefully not to break existing code. For example, the committee recently voted to remove support for function definitions with identifier lists from C2x http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2432.pdf At least one vendor was not very happy with this decision. Undefined behaviors tend to be undefined for a reason and sho…
Why would a vendor be unhappy about that? They have a large library using this deprecated syntax? Or many customers? It seems like a relatively easy fix to existing code.
Tell HN: C Experts Panel – Ask us anything about C
411–420 of 978 posts
Re: Tell HN: C Experts Panel – Ask us anything about C
#412Earlier quoted context omitted.
There were a number of recent proposals to adopt various POSIX functions by Martin Sebor into C including: N2353 2019/03/17 Sebor, Add strdup and strndup to C2X N2352 2019/03/17 Sebor, Add stpcpy, and stpncpy to C2X N2351 2019/03/17 Sebor, Add strnlen to C2X He is lurking on this thread as well. These proposals can all be found in the document log at http://www.open-std.org/jtc1/sc22/wg14/www/wg14_document_log...
There have been some disagreements on strlcpy/strlcat (BSD vs glibc crowd), although by now the debate has died off and these functions are pretty widely used. Also, while here, it would be lovely to have strchrnul() included.
Re: Tell HN: C Experts Panel – Ask us anything about C
#413Earlier quoted context omitted.
> similar to the Annex K Bounds Checked Interface functions strcpy_s and strcat_s but not quite as good IMHO. Err... I thought Annex K is deprecated and dead? Whereas strl* seem very much alive, some compilers even give a "strcpy/strncpy is unsafe, use strlcpy instead" warning.
FWIW, Annex K is not currently deprecated.
Re: Tell HN: C Experts Panel – Ask us anything about C
#414Earlier quoted context omitted.
Correct -- it would be nice if the glibc maintainers would reconsider their opinion of supporting the optional Annex K functionality. There is definitely user demand for the feature.
And every BSD out there. And whatever it is that macOS does. Microsoft looks to be the outlier to me.
> Microsoft Visual Studio implements an early version of the APIs. However, the implementation is incomplete and conforms neither to C11 nor to the original TR 24731-1.
> As a result of the numerous deviations from the specification the Microsoft implementation cannot be considered conforming or portable.
Re: Tell HN: C Experts Panel – Ask us anything about C
#415Other than these experts, what kind of companies do C developers work at? How does the compensation look like compared to doing web development?
The list is very much biased by the sort of analyzer we provide. There are certainly plenty of non-embedded codebases in C and of developers paid to maintain and extend them, it's just that we currently do not work with them as much.
I do not know about whether the compensation is better or worse than for other technologies.
Re: Tell HN: C Experts Panel – Ask us anything about C
#416Are there any plans to "clean up C"? A lot of effort has been put into alternative languages, which are great, but there is still a lot of momentum with C, and it seems that a lot of improvements that could be done in a backwards compatible way and without introducing much in the way of complexity. For example: - Locking down some categories of "undefined behaviour" to be "implementation defined" instead. - Proper ar…
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…
One alternative to adding types is to allow enforcing consistency in some structs with the trailing array:
struct my_obj {
const size_t n;
//other variables
char text[n];
};
where for simplicity you might only allow the first member to act as a length (and it must of course be constant). The point is that then the initializer: struct my_obj b = {.n = 5};
should produce an object of the right size. For heap allocation you could use something like: void * vmalloc(size_t base, size_t var, size_t cnt) {
void *ret = malloc(base + var * cnt);
if (!ret) return ret;
* (size_t *) ret = cnt;
return ret;
}Re: Tell HN: C Experts Panel – Ask us anything about C
#417Earlier quoted context omitted.
An object of any type, initialized or not, can be read by an lvalue of unsigned char (or any character type). That lets functions like memcpy (either the standard one or a hand-rolled loop) copy arbitrary chunks of memory. There's some debate about the effects of reading an uninitialized local variable of unsigned char (like whether the same value must be read each time, or whether it's okay for each read to yield a…
Thanks for your answers. A related question: this article [0] appears to single out memcpy and memmove as being special regarding effective type. Is it accurate? It seems to be at odds with your suggestion that there's nothing stopping me writing my own memcpy provided I'm careful to use the right types. [0] https://en.cppreference.com/w/c/language/object#Effective_ty...
The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is opied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
Re: Tell HN: C Experts Panel – Ask us anything about C
#418 struct foo { int a; void *p; };
struct foo f = {0}; // legal C, f->p initialized like a static variable
struct foo f = {}; // not legal but supported by gcc
To me it would make sense that there is no need to specify a value for any of the members that are intended to be initialized exactly like static variables (and the first member is not special so I shouldn't have to explicitly assign a zero?). However the syntax currently demands at least one initializer.--
2. I recall seeing a proposal for allowing declarations after case labels:
switch (foo) {
case 1:
int var;
// ...
}
This is currently not allowed and you'd have to wrap the lines after case in braces, or insert a semicolon after the case label. Is this making it to c2x?--
3. I've run into some recent controversy w.r.t. having multiple functions called main (and this has come up in production code). In particular, I ran into a program programs that has a static main() function (with parameters that are not void or int and char[]), which is not intended to be the* main function that is the program's entry point.
gcc warns about this because the parameters disagree with what's prescribed for the program entry point. It's not clear to me whether this is intended to be legal or not.
--
4. Looking at the requirements for main brings up another question: it says how main should be defined (no static or extern keyword). However, the definition could be preceded by a static declaration, which then affects the definition that follows:
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern.
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.
Therefore, it is possible to have a main function with internal linkage and a definition that exactly matches the one given in the spec:
static int main(int, char *[]);
int main(int argc, char *argv[]) { /* ... */ }
As one might guess, this program doesn't make it through the linker when compiled with gcc. Is this supposed to be legal? Should the spec perhaps require main to have external linkage, and then allow other functions called main with internal linkage (and parameters that do not match what is required of the external one)?EDIT: ---
Are the fixes w.r.t. reserved identifiers going to make it in c2x? Can I finally have a function called toilet() without undefined behavior?
Re: Tell HN: C Experts Panel – Ask us anything about C
#419Hi, Do you think Annex K of C11 will be widely adopted by programmers or unused? Why aren't people adopting it? Do you see the use of any analysis tools that are particularly effective for finding memory safety issues? C++ added in smart pointers to its specification. Are there any plans to do something similar in future C specifications? Thanks!
Annex K isn't being adopted because it's unergonomic and doesn't solve the problem it purports to. Even the proposer (Microsoft) does not actually implement Annex K as specified in the ISO.
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?
Re: Tell HN: C Experts Panel – Ask us anything about C
#420I'm teaching C to high schoolers as their first language, which is quite the adventure. Do you have any good advice or resources on how to introduce the way C treats the function stack and heap allocated memory? Most of my students struggle (naturally) with making sense of function scoped identifiers and pass-by-value semantics.
This service has been designed to try out small self-contained C examples online (in a manner reminiscent of Compiler Explorer): https://taas.trust-in-soft.com/tsnippet/ One advantage is that it identifies a LOT of undefined behaviors during execution for which traditional compilation and execution only give puzzling results. One drawback is that some of the undefined behaviors it identifies are obscure, and for othe…