Live data from Hacker News

Obvious things C should do

digitalmars.com

211–220 of 310 posts

Re: Obvious things C should do

#211

Header files are one of the things I miss the most about languages that aren't C. Having a very clear distinction between public and private, and interface and implementation is one of my favourite things about C code (at least the way I write it). Being able to just read through a library's .h files to know how to use it is really nice. Typically, my .h files don't really look like my .c files because all the docume…

I think there may be a difference in thinking that underlies the difference in opinion here.

In my experience, having a header file nudges you to think about interface being a _different thing_ to implementation - something that (because you need to) you think about as more fundamentally separate from the implementation.

Folks who think this way bristle at the idea that interface be generated using tooling. The interface is not an artifact of the implementation - it’s a separate, deliberate, and for some even more important thing. It makes no sense to them that it be generated from the implementation source - that’s an obvious inversion of priority.

Of course, the reverse is also true - for folks used to auto-generated docs, they bristle at the idea that the interface is not generated from the one true source of truth - the implementation source. To them it’s just a reflection of the implementation and it makes no sense to do ‘duplicate’ work to maintain it.

Working in languages with or without separate interface files nudges people into either camp over time, and they forget what it’s like to think in the other way.

Re: Obvious things C should do

#212
post #187

Earlier quoted context omitted.

You will be pleased to know that you are not the only one who does this. I previously went down the rabbit hole of fancy unit test frameworks, and after a while I realised that they didn't really win much and settled on something almost identical to what you have (my PRINT_RUN macro has a different name, and requires the () to be passed in - and I only ever write it if the time to run all the tests is more than a sec…

This test/src separation always felt like html/css to me. When still using C, I wrote tests right after a function as a static function with “test_” in the name. And one big run-all-tests function at the end. All you have to do then is to include a c file and call this function. Why would I ever want to separate a test from its subject is a puzzling thought. Would be nice to have “testing {}” sections in other langua…

Because tests also serve as api validations. If you can't write a test for functionality without fiddling with internal details the api is probably flawed. Separation forces access via the api.

Re: Obvious things C should do

#213
post #197

Earlier quoted context omitted.

I disagree with you on this. In another language with explicit public / private separation, the compiler can have access to the internal layout of a type (and thus optimise on it) without letting the developer mess around with it directly. I am assuming static compilation of course. Across a dynamic boundary, I would expect this compiler to behave like a normal C compiler and not use that layout. In a header file, th…

A compiler can still have access to the internal layout in C via link-time optimization.

Linker is something different from Compiler (even if often called via same Frontend)

Re: Obvious things C should do

#214
post #119

Earlier quoted context omitted.

> These kinds of build-failing tests are great for your "I think I'm finished now" build, but not for your "I'm in the middle of something" builds i tend to disagree. If you tried to express some thought but the compile time tests tells you you're wrong, you might actually just have an incomplete thought, or have not thought through all of the consequences of said expression. It's basically what type-checking is in h…

> it forces the programmer to discover corners of their program for which they "know" isn't valid but don't care. And this is precisely why I disagree with forcing it upon the developer at every stage of development. Generally, while in the thick of things, I just want to get things working with one part, not worry about what other parts this breaks (yet). But the pedantic "you have to fix this first" enforcement bre…

> because now I have to split my attention to things I don't want to even be bothered with yet.

One of the reasons could that you realize you don't need those parts, so it would have been a waste of time to write tests for them.

Is that the same as saying I don't want to have to write types either? Maybe. Types are like lightweight incomplete specs.

Re: Obvious things C should do

#215
I consider forward references an anti-feature. I want any language I use to have the following property: if I append to the source file, I can't break previously correct code above the insertion point. Forward references both break this property _and_ requires multiple compiler passes.

More generally though, it's time to stick a fork in c. To me the only sane ways to use c are as a compilation target or for quick and dirty prototypes.

We can't make c better by adding to it. We need to let it die peacefully so its grandchildren may live.

Re: Obvious things C should do

#216
post #197

Earlier quoted context omitted.

A compiler can still have access to the internal layout in C via link-time optimization.

Linker is something different from Compiler (even if often called via same Frontend)

The linker invokes the compiler again.

Re: Obvious things C should do

#217

While the author has WAY more knowledge/experience than me on this and so I wonder how he would solve the following issues: Evaluating Constant Expressions - This seems really complicated...if you're working within a translation unit, thats much simplified, but then you're much more limited in what you can do without repeating a lot of code. I wonder how the author solves this. Compile Time Unit Tests - This is alrea…

> if you're working within a translation unit, thats much simplified, but then you're much more limited in what you can do without repeating a lot of code. I wonder how the author solves this. You are correct in that the source code to the function being evaluated must be available to the compiler. This can be done with #include. I do it in D with importing the modules with the needed code. > This is already somewhat…

Nice explanation. Modules are the way forward. Looks to always have been. Not understanding the resistance, when the advantages are clear.

Re: Obvious things C should do

#218
post #79

I write unit tests for my C code all that time. It's not difficult if you use a good build system and if you are willing to stomach some boilerplate. Here is one test from my "test suite" for my npy library: void test_load_uint8() { npy_arr *arr = npy_load("tests/npy/uint8.npy"); assert(arr->n_dims == 1); assert(arr->dims[0] == 100); assert(arr->type == 'u'); npy_free(arr); } int main(int argc, char *argv[]) { PRINT_…

You will be pleased to know that you are not the only one who does this. I previously went down the rabbit hole of fancy unit test frameworks, and after a while I realised that they didn't really win much and settled on something almost identical to what you have (my PRINT_RUN macro has a different name, and requires the () to be passed in - and I only ever write it if the time to run all the tests is more than a sec…

I agree with all of the above. The only fancy thing which I added is a work queue with multiple threads. There really isn't any pressing need for it since natively compiled tests are very fast anyway, but I'm addicted to optimizing build times.

Re: Obvious things C should do

#219
post #79

I write unit tests for my C code all that time. It's not difficult if you use a good build system and if you are willing to stomach some boilerplate. Here is one test from my "test suite" for my npy library: void test_load_uint8() { npy_arr *arr = npy_load("tests/npy/uint8.npy"); assert(arr->n_dims == 1); assert(arr->dims[0] == 100); assert(arr->type == 'u'); npy_free(arr); } int main(int argc, char *argv[]) { PRINT_…

Your function looks like it's doing I/O, which won't work at compile time test. Here's an example of a unittest for the ImportC compiler: struct S22079 { int a, b, c; }; _Static_assert(sizeof(struct S22079){1,2,3} == sizeof(int)*3, "ok"); _Static_assert(sizeof(struct S22079){1,2,3}.a == sizeof(int), "ok"); The semantics are checked at compile time, so no need to link & run. With the large volume of tests, this speeds…

It is difficult to imagine that compile-time interpretation of tests is faster than compiling and running them for anything more complex. And for trivial stuff it should not matter. Not being able to do I/O is a limitation not a feature.

Re: Obvious things C should do

#220
post #190

Earlier quoted context omitted.

> All the features you mentioned "nice interface, fully searchable API interface, whole public API" are exactly what you get if you open a well written header file in any old text editor. No, you can't, and it's not even close. You have a header file that's 2000 lines of code, and you have a function which uses type X. You want to see the definition of type X. How do you quickly jump to its definition with your "any…

I think the person you're responding to must know all of this. This is stuff that's obvious to anyone who has ever written any code that required using libraries. Unfortunately , people like to pretend to have a gripe with something on the internet just for the sake of arguing. This is the only conclusion I can arrive at when people appear to seriously propose reading a header file in a text editor is somehow better…

Or it just might be that different people prefer different things. I'm a hardcore fan of header files too. Vim is my preferred way of dealing with text and I can do all kinds of magic with it with the speed of though and I prefer to use as plain as possible text files. In the rare occasion when the documentation needs more than ascii stuff it's best practice to write a nice tex and friends documentation plus a real tutorial anyway. And full literate programming style is hard to beat when you are dealing with complex things.
Post reply on HN