Why I am Not a C Programmer

chromatic on 2007-08-18T21:34:11

I just wrote this code for Parrot. I know what it does. I know why it does what it does. I just can't support a language that both allows and requires this:

union { const FLOATVAL *__c_ptr; FLOATVAL *__ptr; } __ptr_u;

#define const_cast_float(b) (__ptr_u.__c_ptr = &(b), __ptr_u.__ptr)


#if INTVAL_SIZE == DOUBLE_SIZE
#  define FLOAT_IS_ZERO(f) (*(INTVAL *)(const_cast_float(f)) == 0)
#else
#  define FLOAT_IS_ZERO(f) (*(HUGEINTVAL *)(const_cast_float(f)) == 0)
#endif


Tradeoffs

jrockway on 2007-08-19T02:32:00

C is all about trading "clean code" for speed and portability.

One one end of the code cleanliness spectrum, is a magical language where the word "DWIM" compiles to the exact code you need to solve your problem. This tends to be slow because it needs to try an infinitely large number of programs before one works. It does have nice syntax, though.

On the other end of the spectrum is a programming language where you solder transistors together until applying current to the input produces the output you expect. Very fast when you run it, not so fast to develop.

Perl tends to be a bit closer to the first example, and C to the second. C is a bit painful, but your program will generally run faster, since you're doing the assuming and the program is doing the executing. Perl tries to do a bit of thinking for you, which is great, but it just doesn't run quite as fast.

Welcome to the real world; the land of compromises.

Re:Tradeoffs

jrockway on 2007-08-19T02:32:39

Guh. Slashcode killed my paragraphs. You get the idea though.

Re:Tradeoffs

bart on 2007-08-19T09:58:51

Use "preview" first and you would have known. And it has a mode, "plain old text", that retains line breaks without having to resort to HTML tags.

Don't "support" it then...

jordan on 2007-08-19T19:13:39

I just can't support a language that both allows and requires this...

You say you can't support such a language, but your actions say something different. You're developing for a project, Parrot, that is implemented in C supports the language.

If you don't want to support the language C, write Parrot in something else. What's that? C has many advantages in terms of portability and performance over alternatives for a project like Parrot? Also, C has this huge installed base, which guarantees high-quality implementations and a large, experienced programming community.

Whether you "cannot support" it or not, you might have to use it for pragmatic reasons. Complaints aside, how would it be different if you did support it?

Re:Don't "support" it then...

chromatic on 2007-08-19T21:09:51

Also, C has this huge installed base, which guarantees high-quality implementations and a large, experienced programming community.

Stop, you're killing me!

Complaints aside, how would it be different if you did support it?

I wouldn't be trying to replace it, that's for sure.

Re:Don't "support" it then...

jordan on 2007-08-19T23:33:31

Also, C has this huge installed base, which guarantees high-quality implementations and a large, experienced programming community.

Stop, you're killing me!

So, what is it that you find funny above? That C compilers are of high quality or that there's a large, experienced programming community surrounding C or both?
I guess you could criticize C compilers for quality, but everything's relative. What language implementations have higher quality compilers available?

The experience and size of the C programming community measures up to those of any other, I would think, except perhaps Java.
Complaints aside, how would it be different if you did support it?

I wouldn't be trying to replace it, that's for sure.

So, which effort of yours is an attempt to replace C? Parrot, Perl6 or both? I have to admit, I thought I'd heard some extreme claims about what Perl6 would do for me, but replace C wasn't one of them.

What will Perl6 NOT do? Will it be the only programming language I ever need?

Re:Don't "support" it then...

chromatic on 2007-08-20T00:01:03

That C compilers are of high quality or that there's a large, experienced programming community surrounding C or both?

Ever try to write a cross-platform C99 application? The standard's most of a decade old now. It'd be lovely if compilers could support it. (Microsoft only has a few thousand programmers. I'm sure they'll get around to it eventually.)

I'd also love to meet a few members of this large, experienced programming community. I could put two or three of them to work!

So, which effort of yours is an attempt to replace C? Parrot, Perl6 or both?

I certainly hope not to need to write in C ever again after both are available. I can't say whether you will, but my goal is that Perl 6 is powerful enough I won't miss C and that Parrot is complete enough I won't need C.

Re:Don't "support" it then...

jordan on 2007-08-20T23:47:43

Ever try to write a cross-platform C99 application? The standard's most of a decade old now. It'd be lovely if compilers could support it. (Microsoft only has a few thousand programmers. I'm sure they'll get around to it eventually.)


I have to admit, I haven't done a lot of checking for strict C99 compatibility. From what I'm given to understand, everybody except Microsoft does an excellent job of supporting the C99 standard.

Microsoft not supporting cross platform development. Shocking!!

I'd also love to meet a few members of this large, experienced programming community. I could put two or three of them to work!


Try the P5P mailing list. I understand that many good C programmers hang out there. Also, there's a tiny project called the Linux kernel that seems to have some people with strong C skills.

wtf

educated_foo on 2007-08-19T20:19:59

For us ignoramuses in the audience, how is that any better than const FLOATVAL cf; float * f = (FLOATVAL *)?

Re:wtf

chromatic on 2007-08-19T21:19:19

Compilers warn (rightfully so) that comparing floating point values is notoriously inaccurate. One decent way to compare them anyway is to cast them to pointers and then compare them as integers. Of course, to do that, sometimes you have to cast away constness, hence the ugly, awful, horrible union hack.

Re:wtf

chibiryuu on 2007-08-20T13:47:25

Why can’t you just use
#if INTVAL_SIZE == DOUBLE_SIZE
#  define FLOAT_IS_ZERO(f) (*(INTVAL *)&(f) == 0)
#else
#  define FLOAT_IS_ZERO(f) (*(HUGEINTVAL *)&(f) == 0)
#endif
?

Re:wtf

educated_foo on 2007-08-20T15:39:29

Ugh, I mangled it in my last post (stupid &...), but I was curious why you didn't cast away constness using a cast to FLOATVAL*. gcc -Wall doesn't carp about it on my system:

const float cf;
float * f = (float *)&cf;

Re:wtf

chromatic on 2007-08-20T16:52:09

gcc -Wall doesn't report very many errors. We have -Wcast-qual enabled, which does warn on that construct.

Re:wtf

educated_foo on 2007-08-21T13:20:05

To me that say the problem in this case isn't C, but -Wcast-qual. I tend to just assume that since a cast says that you deliberately chose to break the rules, it's always a sign that the programmer decided to do something risky. I don't find it particularly helpful for the compiler to complain about the rule he broke, since he already broke it on purpose. YMMV, of course.

Re:wtf

chromatic on 2007-08-21T18:06:00

It's awfully easy to cast away constness accidentally, as you have to put const on all of the casts to retain it. It's a useful warning.

Re:wtf

chibiryuu on 2007-08-21T21:26:50

So the warning is valid but should be ignored here.

I'd prefer the simpler-but-generates-a-warning over the ugly-mess-to-work-around-warning code.  Unless you've got -Werror, which is just annoying, and there really should be a way to fine-tune warnings (because you really do know what you're doing here).

Come to think of it, what about
#if INTVAL_SIZE == DOUBLE_SIZE
#  define FLOAT_IS_ZERO(f) (*(const INTVAL *)&(f) == 0)
#else
#  define FLOAT_IS_ZERO(f) (*(const HUGEINTVAL *)&(f) == 0)
#endif
?  That should avoid warnings.