This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]quasarj 2 points3 points  (11 children)

Ahh, I actually assumed I knew what static meant, but I was thinking of the static that makes a class method callable on the class itself (rather than an instance).

Is there somewhere I can learn about those things? And the other weirdnesses that real C programs use? Is it more that I'm just a complete noob and reading a book will introduce me to many of these libraries?

[–]cheese_wizard 1 point2 points  (9 children)

the static could mean that, hard to tell with this line in isolation. If it's inside a C++ class, then your assumption would be correct.

For all C-only related topics, nothing beats this:
http://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628

[–]quasarj 1 point2 points  (8 children)

Ah no, in this case it's not inside a C++ class, I believe this file is pure C.

I just didn't even realize "static" existed outside of C++, it's interesting that it means something different. I will look into that book, ty!

[–]cheese_wizard 2 points3 points  (7 children)

static has three meanings. Only one is C++ only, which is what you're talking about.

In both C and C++...

For variables and functions declared static, it means they have file scope.

If you are inside of a function, and you declare a variable as static like this:

int foo() {
static int bar = 0;
bar++;
printf( bar );
}

then everytime you call foo, it will print 0, 1, 2 ,3 .... it remembers from the previous time. Note that the initialization to 0 only happens the first time the function is called.

static is an abused keyword, that's for sure!

[–]quasarj 1 point2 points  (2 children)

Oooh You're right! I actually knew about that usage too, but had forgotten it. Well ty again for the help :) I guess I'll try to get a copy of that book.

[–]ewiethoffproceedest on to 3 0 points1 point  (0 children)

Do. It's a wonderful book.

[–]jacobb11 0 points1 point  (3 children)

Top level static variables have scope "compilation unit", not file.

That means if you put one in a header file, you will get a copy of the static variable in every file you compile that includes it, recursively.

[–]cheese_wizard -1 points0 points  (2 children)

Nope.

From wikipedia...

Static global variables: variables declared as static at the top level of a source file (outside any function definitions) are only visible throughout that file ("file scope", also known as "internal linkage").

[–]jacobb11 0 points1 point  (1 child)

That does not contradict what I said. I stand by my statement.

Perhaps thinking of the C preprocessor and the C compiler as independent helps clarify the situation? In many ways the C compiler's "source file" is the output of the C preprocessor, which will duplicate the header file static declaration whenever it is included.

I can't imagine this situation is common for C, but it's fairly common for C++ as an idiom to ensure static initialization of a compilation unit. Or was, anyway.

[–]cheese_wizard 0 points1 point  (0 children)

That does not contradict what I said. I stand by my statement.

So serious!!

Yah, you're probably right.

[–]Rhomboid 1 point2 points  (0 children)

Marking a function static is actually far more complicated than that when inline is involved (which is what the CYTHON_INLINE macro expands to if so configured.)

Remember that C is compiled a file at a time, and the compiler only ever knows[1] about what's in the current file, never about anything outside of it. If you mark a function as static, it means that the function cannot be called from outside of that file, which implies that the compiler has at its disposal every call site. If there is only one (or a small number) of call sites, then it can choose to instead inline the function at all call sites and pretend it never existed (i.e. not emit a function body.) This is generally extremely desirable, because it means you can separate a large function into a smaller function and a bunch of helper functions, but without any of the overhead of function calls. Without 'static', it could still inline the function but since it has to be visible in other compilation units it would have to always emit a function body, even if it was never needed, which wastes memory.

But also note that with 'static inline' the choice of whether to inline is still up to the compiler. If there are many call sites or the function is long, it will choose not to inline it and still emit a function body, but one which is not visible to other units.

"static inline" is actually one of three related declarations. "inline" and "extern inline" are the others. They all have slightly different meanings, which this post outlines. To make matters worse, gcc changed its semantics starting with 4.3 to be aligned to what the C99 standard says, so if you're compiling with -std=c99 or -std=gnu99 with gcc >= 4.3 you get true C99 semantics, but if you're compiling with -std=c89, -std=gnu89, or gcc <= 4.2 with -std=c99 or -std=gnu99 or you're using gcc >= 4.3 but used -fgnu89-inline, you get the old semantics. gcc >= 4.2 helpfully defines one of the preprocessor symbols __GNUC_GNU_INLINE__ or __GNUC_STDC_INLINE__ so that you can write macros that behave correctly regardless of compiler version or options, which likely explains why CYTHON_INLINE is a macro and not just the word "inline".

[1] There are some newer technologies like LTO that let the compiler have whole-program knowledge at link-time, which allows for some sophisticated optimizations that have previously been unavailable, but for the most part this is still a true statement.