Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
C Ints are Finite Numbers (freebsdish.org)
79 points by anon1385 on Aug 17, 2013 | hide | past | favorite | 24 comments


As someone who write C for a living, this _Generic macro scares me a little. It looks like C++ templates using C macros, and like everything with the C preprocessor it's a hack on top of a hack.

We all know the C macrolanguage has a ton of shortcomings. But adding all those weird, un-C-like behaviours just makes code harder to understand IMO. You don't expect templates in C code. I don't have anything against C++, but what's the point of C if it just becomes "like C++ but with macro hacks".

If the people responsible for the C standard feel the macrolanguage needs fixing, they have all my support. But let's actually fix the language or design a new one, not add quick hacks that change the semantics of the C code for, IMO, small gains.


<pedantic>_Generic is not a macro; it just is used a lot inside macros. You should see it as a switch on the type of its argument.

This also aren't templates; you still have to write all those variants for a function, and give them unique names.

More importantly, I think this is worth the hassle. Before this, you couldn't really do

   typedef double number_t;
and then easily call functions in the standard library such as sin, acos, or pow without having to worry about the actual type of that typedef. _Generic allows library developers to hide the ugliness of having different names for similar functions. That might have been possible using preprocessor metaprogramming, but it certainly wasn't simple.


A fair point, but I think your example demonstrates what I'm worried about: for each legitimate use of this construct there will be a billion of bogus/leaky implementations that we'll have to debug in a couple of years.

If I want to write "sin(a);" and let the compiler figure out which implementation of sin to use, I can already do that today. I use C++.

It's a bit late to turn C into a strong-ish typed language...


If you accept "If I want to do X, I can already do that today. I use C++" as an argument, I don't think there is much to be done improving C. You may be able to add a header file here and there before C++ gets it, and you may be able to fix some dark corners of the language, but the big picture would be one of stagnation.

Stagnation in programming languages leads to death, so you would accept that C will eventually die, with C++ being its replacement/killer. That is not necessarily a bad thing, and one could argue that it already is happening (are there still self-hosting C compilers?), but I think it is something one should realize the moment one uses that argument.


My understanding is that programming languages exist because they attempt to solve an existing problem under a defined paradigm.

I'm not against borrowing features from other languages when they can be ported without affecting the paradigm, but when they do... does it mean the language will die without a specific set of features?

I believe it's the project manager's responsibility to evaluate whether the problems a project will solve can be solved with a specific language before taking the decision to use it.

A language will never be an "all-in-one solution" and forcing a language to solve a problem it was not designed to solve will lead to extra work in the best scenario, ex. String Manipulation in C.

My perception about C is that it was the best option available when it emerged, but newer languages emerged that managed to solve specific problems in a better way than C.

For me this doesn't mean that C is a "dying language", but the completely opposite, C has become a specialized language suitable for use cases where higher level languages mean "expensive overhead", but lower level languages mean "expensive complexity".


This is old hat in FORTRAN, and has been for decades. The idea is that numeric code should have sin(x), not sind(x) and sinf(x).


i don't share your fear, but i was surprised by it.

then i realised i didn't really know c11. so i checked amazon and there's no c11 harbison + steele. so i just emailed harbison to see if a new edition is planned.

if i get a reply i'll update here.


just got a reply - "At this time there are no plans for another edition." :o(


You're not wrong to be concerned; all things beginning with '_' are reserved for use by the implementation:

http://stackoverflow.com/questions/228783/what-are-the-rules...

Update: as another person points out, _Generic is now an official keyword as of C11.


_Generic is a language keyword, not a user-defined macro. It uses an underscore-prefixed name (along with many other C11 keywords/features) precisely because those names are reserved and won't conflict with user code.

Also, that SO post is about C++, not C. It might seem pedantic (particularly given that C actually does have the same rule for reserved names), but that's something to be careful about as there's significant divergence nowadays.


Sorry; I didn't realise that _Generic is a C11 keyword:

http://en.wikipedia.org/wiki/C11_(C_standard_revision)

  Also, that SO post is about C++, not C.
No, it's about both C++ and C:

  Because C++ is based on the C standard (1.1/2, C++03) and
  C99 is a normative reference (1.2/1, C++03) these also
  apply, from the 1999 C Standard...
See section 7.1.3 of the relevant standard:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

Also, the divergence has actually been lessened since the C++11 committee worked closely with the C11 committee to bring the standards closer together.

That's part of why Microsoft is picking up a lot of C99 as part of their work for implementing C++11.


Good catch on the C/C++ standard relation, I somehow completely missed that when I read the SO answer. Glad to hear that that situation is improving.


Odd choice of title, given that the post is about 'isinf(someInt)' being a compile error (as opposed to treating ints as finite and returning false).


Well I suppose it probably should be. `isinf(someInt)` makes no sense to call and is most likely a logical error. Moreover, it's not defined, so you could have (pseudocode)

    isinf(x)
      if (isint(x))
         return random() < 0.5
      else
         ...
I think the title makes sense, as it's about c ints being finite, and therefore nobody should be calling "isinf" with them. It was interesting that several codebases were.


While the title is true factually, it does not reflect the main point (using C11 features to improve on unsafe preprocessor constructs). I was almost tempted to say "Yeah... so?" and move on. I am glad I did not, but there are almost certainly others who did.


Isn't this really an error in the spec though? Based on what the words mean, isinf and insnan logically should always return false when called with an int argument.


Only in the same way that it's an error that the spec doesn't define isinf for strings.


> isinf and insnan logically should always return false when called with an int argument.

Yes, but the thing is, they are defined only for floating point types in standard


Odd title, interesting article. Almost didn't read it, glad I did.


I thought this would be about the dangers of not checking for integer overflow.

I struggled to come up with a method which, in C, safely converts a string to an integer type. I finally did it¹, but I've yet to see someone else use this method.

1) http://stackoverflow.com/a/542833/54435


I can imagine this happening in template code:

    template <typename T>
    bool isNumberInfinity(T number)
    {
        return isinf(number);
    }

    template <>
    bool isNumberInfinity(Number number)
    {
        return number == Number::INF;
    }

So instead of specializing ints, we rely on isinf working for ints, instead of doing the "correct" thing:

    template <>
    bool isNumberInfinity(int number)
    {
       return false;
    }
This is a very contrived since I'm using template functions, which are practically useless, but it holds for any data structure which holds a type that is meant to behave somewhat like a "number".


What do you mean by "template functions are practically useless"?


Can anyone here provide an explanation for why some code that is supposed to be high quality and trusted is calling isnan(int)?

That seems to be the more pressing issue here, not the (long since done) inclusion of a new feature in C!


Usually, whenever there's something weird being done in C, it's because of macros or other forms of code generation.

However in the case of floating point vs integers, it's also likely that a literal is missing a decimal.

    1/4 != 1.0/4




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

Search: