←back to thread

271 points mithcs | 1 comments | | HN request time: 0s | source
Show context
miroljub ◴[] No.45953073[source]
Nice toy. It works until it stops working. An experienced C developer would quickly find a bunch of corner cases where this just doesn't work.

Given how simple examples in this blog post are, I ask myself, why don't we already have something like that as a part of the standard instead of a bunch of one-off personal, bug-ridden implementations?

replies(2): >>45953149 #>>45953168 #
Borg3 ◴[] No.45953149[source]
Yeah, kids like to waste time to make C more safe or bring C++ features. If you need them, use C++ or different language. Those examples make code look ugly and you are right, the corner cases.

If you need to cleanup stuff on early return paths, use goto.. Its nothing wrong with it, jump to end when you do all the cleanup and return. Temporary buffers? if they arent big, dont be afraid to use static char buf[64]; No need to waste time for malloc() and free. They are big? preallocate early and reallocate or work on chunk sizes. Simple and effective.

replies(4): >>45953181 #>>45953199 #>>45953578 #>>45953726 #
1718627440 ◴[] No.45953578[source]
> static char buf[64];

In a function? That makes the function not-threadsafe and the function itself stateful. There are places, where you want this, but I would refrain from doing that in the general case.

replies(1): >>45958214 #
Borg3 ◴[] No.45958214[source]
Holy moly.. Thread safety.. Good point and Bad point. I myself use threads sparsly, so I dont intermix calls between threads..
replies(1): >>45959850 #
1718627440 ◴[] No.45959850[source]
It also has different behaviour in a single thread. This can be what you want though, but I would prefer it to pass that context as a parameter instead of having it in a hidden static variable.
replies(1): >>45966221 #
Borg3 ◴[] No.45966221[source]
What different behaviour you mean? static in function means that this is just preallocated somewhere in data, not on stack nor heap. Thats it. Yes, its not thread safe so should never be used in libraries for any buffering.

But in program, its not bad. If I ever need multiple calls to it in same thread:

  static char buf[8][32];
  static int z;
  char *p=buf[z];
  z=(z+1)&7;
Works pretty well ;)
replies(1): >>45967460 #
1718627440 ◴[] No.45967460[source]
> What different behaviour you mean?

Static foremost means that the value is preserved from the last function invocation. This is very different behaviour, than an automatically allocated variable. So calling a function with a static variable isn't idempotent, even when all global variables are the same.

> If I ever need multiple calls to it in same thread:

What is this code supposed to do???? It hands out a different pointer, the first 8 times, than starts from the beginning again? I don't see what this is useful for!

replies(1): >>45970551 #
Borg3 ◴[] No.45970551{3}[source]
If you want to return some precalculated stuff w/o using malloc() free(). So you just have 8 preallocated buffers and you rotate them between calls. Of course you need to be aware that results have short lifetime.
replies(1): >>45972260 #
1718627440 ◴[] No.45972260{4}[source]
That sounds like a maintenance nightmare to me. If you insist on static, I would at least only use one buffer, to make it predictable, but personally I would just let the caller pass a pointer, where I can put the data.

What application is that for? Embedded, GUI program, server, ...?

replies(1): >>45977290 #
1. Borg3 ◴[] No.45977290{5}[source]
it is very predicatable.. Every call it returns buffer, after 8 calls it wraps. I use such stuff in many places.. GUI programs.. daemons.. Most stuff are single threaded. If threads are used, they are really decupled from each other.

Yes, you should never ever use it in Library.. But small utility functions should be okish :)

This is example from my Ruby graph library. GetMouseEvent can be called alot, but I need at most 2 results. Its Ruby, so I can either dynamicaly allocate objects and let GC pickup them later, or just use static stuff here, no GC overhead. it can be called 100s of times per second, so its worth it.

  static GrMouseEvent evs[8];
  static int z=0;
  GrMouseEvent *ev=&evs[z];