lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Sat, Apr 19, 2014 at 1:38 PM, Sean Conner <sean@conman.org> wrote:

>   In general, I tend to use inline (imagine that!  the equivalent of
> typesafe macros but portable!), restrict (still working out if that's a win
> or not---at the very least it documents intent), and declaring local
> variables in for loops, like:
>
>                 for (int i = 0 ; i < SOME_MAX; i++)
>                 {
>                         /* ... */
>                 }

Hmm, I'd like to kindly point out that inline is a request and not a demand :>

Also, functions do get aggressively inlined in C89, but the code for
the function itself is always emitted (unless the eventual binary is
not a library and the function is never used).  Marking something as
inline in C99 is a request, and if the compiler can prove that the
function isn't referenced externally it can omit generating the
function itself -- while still inlining the body where it's used.
inline is something I've missed a lot of sleep over... :(  Anyway,
it's at least worth knowing that C89 compilers aggressively inline per
the right -O flag as well.  At least restrict is taken seriously, C++
doesn't have anything like it for avoiding pointer aliasing (which is
why people still love Fortran) -- I think the only STL container that
can is std::array (unsure).  Limiting scope by declaring the
accumulator within the for loop header is nice. :-)

> The named field initialization feature of C99 is also nice:
>
>         struct itimerval x =
>         {
>           .it_value =
>           {
>             .tv_sec = 5,
>             .tv_usec = 500000
>           },
>
>           .it_interval =
>           {
>             .tv_sec = 3,
>             .tv_usec = 250000
>           }
>         };

I do like this -- I had to take a C++ class last semester for college
and I was annoyed that C++ didn't have this until a friend pointed out
that constructors make it largely unnecessary.  There's a very good
PDF floating around from Nokia on API design that's worth a read.
It's somewhat related to this -- it encourages writing constructors
and single-member initializers -- getters and setters in the form of
member()/setMember():  http://www4.in.tum.de/~blanchet/api-design.pdf

>         if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&(int){1},sizeof(int)) < 0)
>           error();

I think what you have there is a compound literal, bro: &(int){1}

It can make for some concise code not many people are familiar with
them... it's a tradeoff between concision and readability.  Cool
though :-)

>   I also love <stdint.h> and <stdbool.h>.  The former replaces a large block
> of preprocessor code I used to use to get known sized integers, and the
> later gives me booleans, true and false (okay, so booleans are a bit larger
> than 1 bit, but hey, I can live with that).

I think we all wish booleans were 1-bit for memory concerns, but
accessing word-sized primitives is much faster -- which is why it's
traditionally defined as an int.

I find myself doing this even if 'bool' does exist because I have to
write code for both WIndows, sometimes Solaris, and the non-fucky
platforms:

typedef int boolean;

#if true
#elseif
#    define true 1
#endif

#if false
#elseif
#    define false 0
#endif

I know it looks weird to not just use 'ifndef' but iirc on older
compilers ifdef/ifndef aren't recognized -- maybe that's more paranoia
on my end.

>   alloca() is not standard.  It's a compiler hack that is found on several
> copilers (you can't write the function at all---it *has* to be a compiler
> hack).

Pretty sure you can do it with assembly, but it of course wouldn't be
portable... I don't have that code in front of me right now :(
>
>> Going the route of luaL_Buffer would still
>> allocate on the heap (internally using Lua's set allocator function --
>> which looks like realloc).  I'm continually mad at Microsoft for not
>> better supporting C99 but in the grand scheme of things I'd rather
>> skip C99 entirely.  It doesn't add enough to be worth jumping ship.
>
>   Have you really looked at it?

Looks like heap allocation to me.... ?
http://www.lua.org/source/5.2/lauxlib.c.html#luaL_prepbuffsize

Anyway, the other guy is right -- allocating on the stack could be a
bad thing for especially large strings.  I'm sure for your use cases
an overflow never happens, and allocating from the stack is much
faster than from the heap so I can see why you did it.

>> ((Yes I do curse the people who only have C89 runtimes at their
>> disposal, but nobody completely supports C11 yet... stupid glibc))
>
>   It's been fifteen years since C99 and how many people use it?  At this
> stage in the game, I'd be surprised if anyone picks up C11 ...

My point is that C99 wasn't worth supporting in whole right away -- my
opinion of C11 is different.  Atomics, threading, and aligned memory
allocation are HUGE wins (imo).  I really hope glibc gets on the ball
because it'll be a while before we see it in the smaller libc's...
(musl and such)