Hacker News new | past | comments | ask | show | jobs | submit login

A few proposals:

Why not mandate a warning every time the compiler detects and makes use of UB? It would solve SO many issues. If you are looking to improve security of C programs, then letting the user know what the compiler does should be number one.

Try to convert as many UB's to Platform specific, as possible would also be a big help.

I would love to see native vector types. Its time. Vector types are now more common in hardware then float was when it was included in the C spec. Time to make it a native type. Hoping the compiler does the vectorization for you is not good enough.

Allow for more then one break.

for(i = 0; i < n; i++) for(j = 0; j < n; j++) if(array[i][j] == x) break break;

is equal to:

for(i = 0; i < n; i++) for(j = 0; j < n; j++) if(array[i][j] == x) goto found; found :




> Why not mandate a warning every time the compiler detects and makes use of UB? It would solve SO many issues.

Because that's hardly ever what happens, except when it actually does, and compilers do an increasingly good job of issuing diagnostics in that case. If you actually mandated it, no compiler today would come close to being standards compliant. This comes close to making the language unimplementable.

The most common issue with UB and optimizations is not that "compiler detects UB and does something with it," it's that compiler analyzes and optimizes code with the assumption that UB doesn't actually happen. It doesn't know whether it does (and in general, it is impossible to tell whether it would happen -- it's something that might or might not happen at run time, and proving it one way or another amounts to solving the halting problem), it just assumes it doesn't.

And if one mandated compilers to report every time they make an optimization that is valid under the assumption that the program is well behaved, then you would never finish reading compiler output. Or you would turn off optimizations.


They need to do better then remove NULL checks silently. You can read all about Linus rants on this. Every time the compiler breaks things they blame the C standard for letting them do what ever. Thats whats wrong with C today. The C standard hasn't put its foot down.


I want my compiler to remove redundant checks (without any noise), and that is why I pass it an optimization flag. If you don't want such optimizations, then maybe you should not ask the compiler to make them.


This attitude is terrible! Its an attitude that says that unless you know exactly every pit fall in the language by heart you have no place writing code. I guess you dont use a debugger either because you never write bugs right? And you think that every software that helps the user is for noobs right?

There is an endless list of bugs that have been produced by very competent C programmers, because the compiler has silently removed things for some very shaky reasons.


Huh? I just want performant code. That's why I write C, and that's why I use an optimizing compiler, and that's why I ask my compiler to optimize.

I also want to write code that is reasonably generic. Thus, it will have checks and branches that cover important corner cases; they are required for completeness and correctness. But very often, all of these checks turn out to be redundant in a specific context, and an optimizing compiler can figure it out, and eliminate these checks for me.

So I don't manually need to go and write two or three versions of each function like do_foo and assume_x_is_not_null_and_do_foo and assume_y_is_less_than_int_max_minus_sizeof_z_and_do_foo and make damn sure not to call the wrong one.

I just write one version, with the right checks in place, and if after macro expansion, inlining, range analysis, common subexpression elimination, and other inference from context, with C's semantics at hand, the compiler can figure out that some of these checks are redundant, then it will optimize them out.

I ask for it, and I'm glad compiler developers deliver it. You don't need to ask for it. Just turn off these optimizations (or, rather, don't enable them) if you prefer slow and redundant code.


Why can't the following be a warning?

    int foo(bar *x)
    {
      x->blah = 0;
      if (x == NULL) ... 
      ...
    }
And produce something like "NULL check removed---pointer used before check"?


In theory? No reason.

In practice it's a special case of a more widely applicable optimization where you actually do want to remove redundant checks. So someone has to go out of their way to figure out a rule that makes the compiler warn but only in cases where a human reader finds the optimization surprising and undesirable. It's a fuzzy thing and can easily lead to lots of false positives and noise (and more whining because it didn't warn in a situation that someone considered surprising).

I think that kind of logic can easily become a support & maintenance nightmare, so I'm not surprised that compiler developers take their time and are conservative when it comes to adding such things. I would probably just ask you to either stop dereferencing NULL pointers, or turn off the optimization if you want to dereference NULL pointers and eat your cake too.


This is a very naive view of how C works in reality. Take this example:

if(a == NULL) log_error_and_exit(); *a = 0;

Compilers, have been known to silently remove the NULL check in code like this. Does that seem clear to you? Is this your definition of compilers delivering for you? NULL checks dont just get removed in cases where you NULL check the same value multiple times, they get removed for some very non obvious reasons.

This is why the Linux kernel now needs to be built with the compiler option -fdelete-null-pointer-checks

Compilers need to start communicating what they are doing, and I think the C spec should encourage that.


You probably mean -fno-delete-null-pointer-checks?


Most compilers will no longer do this, FWIW.


A multiple-level break is a good idea, but I think that Java's labeled break is a better way to do it:

    find_in_array_loop:
    for(i = 0; i < n; i++)
        for(j = 0; j < n; j++)
            if(array[i][j] == x)
                break find_in_array_loop;




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: