Live data from Hacker News

Some dark corners of C

docs.google.com

151–160 of 175 posts

Re: Some dark corners of C

#151
post #144

Earlier quoted context omitted.

> If your code lacks the declaration of the function, the compiler will assume pre ANSI-C semantics and generate code returning an int. Better, please help by compiling your C code with -Wimplicit-function-declaration (included in -Wall), and fixing all the problems it reports. Then you won't have to worry about this problem, or a bunch of other problems.

All-too-common response: "Oh, but they're just warnings mumble compiles and runs 'cleanly' mumble..."

    -Wall -Wextra -Werror

Re: Some dark corners of C

#152

Earlier quoted context omitted.

1) malloc() and free() are just library calls, they're not first class citizens of the language. K&R and other good C references describe their public interface well and that's all you need to know to use them effectively. The public interface encapsulates the implementation details, good software engineering in my book. 2) Usage of the stack reflects C's low-level, high performance "portable assembler" roots. Choosi…

1) On malloc() and free(), right, I was free just to write my own. I should have. At various times since for various reasons, I have just written my own. On your "K&R and other good C references describe their public interface well and that's all you need to know to use them effectively." I want more. By analogy, all you need to drive a car is what you see sitting behind the steering wheel, but I also very much want…

C is not perfect. It has its problems (strings, ++, horrible type syntax, no memory allocation, architecture idiosyncrasies like type width). However, it's reliable, fast, and you can basically memorize the language and compile it by hand if necessary. No other language will reliably run on many systems that fast with that much existing code.

anyway, if you think you can prevent bad code by using restrictive languages, you're gonna have a bad time. Any language can be abused. Just don't abuse it, treat your code with respect.

Also I'm pretty sure j+++++k has undefined behavior so you should be shot if you write it.

> in my startup I don't want us using a language that permits code like that.

Well I hope you don't run unix or windows, python or ruby, Firefox, chrome, ie, safari, or opera, or use a smartphone.

Re: Some dark corners of C

#153
post #116
post #59

Earlier quoted context omitted.

An annoying thing C++. Anyone know the history/rationale of this change?

It is supposed to provide you more checking by disabling automatic cast from void* to any other pointer. This makes sense in C++ since casting a pointer to a class can trigger some address adjustement if the target class of this instance pointed to is multiple derived (and maybe in other cases?). There is no way such adjustment can happen if the source type is void*, because then you don't know what the source type r…

As far as I know, this is exactly the rationale, actually. Say you have:

  struct a { int a;}
  struct b { int b;}
  struct c : a, b { };

  c myc;
  c* p1 = &myc;
  b* pb1 = p1; // correctly points to myc's base b, which is offset

  void* p2 = &myc;
  b* pb2 = p2; // Would not point at instance of b, compile error
If I need void*-casting code to compile on both C and C++ compilers, I use a macro like this:

  #ifdef __cplusplus
  #define STATIC_CAST(T, EXPR) static_cast(EXPR)
  #else
  #define STATIC_CAST(T, EXPR) (EXPR)
  #endif
This leaves the conversion to be implicit in C, and uses the stricter static_cast in C++ to catch certain types of likely-unsafe conversions, such as the aforementioned cast from int to pointer.

Re: Some dark corners of C

#155
post #17
post #3

#define struct union #define else That's evil. I have to do it in someone's code some day just to have some fun. But, apart from that, it's a really nice compilation. I didn't know about the compile time checks of array sizes, but I have a doubt. What if I pass to a method declared int foo(int x[static 10]) this pointer int* x = (int*) calloc(20, sizeof(int)); Does the compiler skip the check? Does it give me a warni…

It's impossible to have a static decision procedure about dynamic properties of programs, such as the size of dynamically allocated memory areas (Rice's theorem). So, it is necessary to either include false positives (correct programs rejected) or false negatives (incorrect programs accepted). Sound static analyzers fall in the first case, but require a lot of work to become precise enough to be used (ie, to reduce t…

> It's impossible to have a static decision procedure about dynamic properties of programs, such as the size of dynamically allocated memory areas (Rice's theorem).

You can not have a general procedure, but with the help of the programmer / user of the compiler, you can prove all kinds of things.

Re: Some dark corners of C

#156
post #47
post #30

Earlier quoted context omitted.

It replaces the first word with what comes after. For example, #define foo bar is roughly equivalent to s/foo/bar/g, so #define else would just remove all else keywords. I'll let you guess what it does to a program.

Not to forget #define struct union which will pack all struct members together. Gives me chills even to think about it...

It's a great memory saver.

Re: Some dark corners of C

#157
post #128

Earlier quoted context omitted.

A self-proclaimed expert, one must add.

I don't know dakimov and what his history may be (maybe it's even a language issue or that he simply doesn't "speak HN" yet - I also sometimes find myself out of touch with the culture on this site like he seems to be), but I can vouch for what he's saying. I find it difficult to read discussions about C on HN. A lot of the discussion is as if to read a bunch of kids who seemingly just learned javascript or ruby yest…

I am an experienced and self-proclaimed competent C programmer and I was surprised enough by the "static" feature which I already love -- that I immediately upvoted this, and I'm going to spread this information after testing that it is actually usable with the common tools we use.

Sure, the other stuff was either UB or less interesting to experienced C programmers, but I'm not sure why that should be a problem. If you already know all of these, then you're not the intended audience. You can comment from a more experienced position, or just move along.

Bragging about knowing all of those and even worse - claiming they are just silly UB, all in a condescending tone as dakimov did, is a very stupid thing to do.

Re: Some dark corners of C

#158
post #154

What's the point in 'count up vs. count down'?

Integer subtraction with a result of 0 sets the same status bit as comparing one value to another, so you can get away without the compare instruction when counting down. It might not sound like a lot, but it can be meaningful in a tight loop.

I don't know why the author chose to change the syntactic structure of the loop though, since it hides the point.

You have to be careful when counting down though. If you're accessing an array, you might be tempted to do this:

    for(size_t i = bar_len - 1; i >= 0; --i) {
        foo(bar[i]);
    }
It looks innocent enough, but size_t is unsigned, so i >= 0 will always be true. (Of course, using -Wall and -Wextra will warn you about this.)

Re: Some dark corners of C

#159
post #113

Earlier quoted context omitted.

> While we're talking about dark corners, please stop casting functions that return void * The problem is, if I want my C code to compile with MSVC, it has to compile as C++ - and even if I abhor Windows for development myself, a lot of developers are using MSVC. I just wish Microsoft would update their C compiler, at least to C90. But then I suppose the standard has only been around for 23 years, and nobody really u…

> The problem is, if I want my C code to compile with MSVC, it has to compile as C++ As someone who has compiled a lot of .c files that do not cast void pointers with cl.exe, I'd say no, this is not true... Maybe what you're trying to say is that your code relies on C99 features that are also present in C++? IMO if that's what's holding you back it's much easier to just write C89, maybe with the occasional ifdef, tha…

You're suggesting I write C89 in 2013 just to support MSVC? C89 in which you can't even mix data and code?

I think casting void pointers is very much the lesser of two evils. And of course I can use MinGW, but that doesn't mean the majority of Windows developers don't insist on using MSVC.

Re: Some dark corners of C

#160
post #159

Earlier quoted context omitted.

> The problem is, if I want my C code to compile with MSVC, it has to compile as C++ As someone who has compiled a lot of .c files that do not cast void pointers with cl.exe, I'd say no, this is not true... Maybe what you're trying to say is that your code relies on C99 features that are also present in C++? IMO if that's what's holding you back it's much easier to just write C89, maybe with the occasional ifdef, tha…

You're suggesting I write C89 in 2013 just to support MSVC? C89 in which you can't even mix data and code? I think casting void pointers is very much the lesser of two evils. And of course I can use MinGW, but that doesn't mean the majority of Windows developers don't insist on using MSVC.

C++ is not a superset of C[0]. If you want to use MSVC and newer features, then you're not writing C anymore; you're just writing an awkward C++ program.

[0] http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

Post reply on HN