Best c questions in February 2011

Redefining NULL

62 votes

I'm writing C code for a system where address 0x0000 is valid and contains port I/O. Therefore, any possible bugs that access a NULL pointer will remain undetected and at the same time cause dangerous behaviour.

For this reason I wish to redefine NULL to be another address, to for example an address that isn't valid. If I accidentally access such an address I will get a hardware interrupt where I can handle the error. I happen to have access to stddef.h for this compiler, so I can actually alter the standard header and redefine NULL.

My question is: will this conflict with the C standard? As far as I can tell from 7.17 in the standard, the macro is implementation-defined. Is there anything elsewhere in the standard stating that NULL must be 0?

Another issue is that plenty of compilers perform static initialization by setting everything to zero, no matter the data type. Even though the standard says that the compiler should set integers to zero and pointers to NULL. If I would redefine NULL for my compiler, then I know that such static initialization will fail. Could I regard that as incorrect compiler behaviour even though I boldly altered compiler headers manually? Because I know for certain that this particular compiler does not access the NULL macro when doing static initialization.

The C standard does not require null pointers to be at the machine's address zero. HOWEVER, casting a 0 constant to a pointer value must result in a NULL pointer (§6.3.2.3/3), and evaluating the null pointer as a boolean must be false. This can be a bit awkward if you really do want a zero address, and NULL is not the zero address.

Nevertheless, with (heavy) modifications to the compiler and standard library, it's not impossible to have NULL be represented with an alternate bit pattern while still remaining strictly conformant to the standard library. It is not sufficient to simply change the definition of NULL itself however, as then NULL would evaluate to true.

Specifically, you would need to:

  • Arrange for literal zeros in assignments to pointers (or casts to pointers) to be converted into some other magic value such as -1.
  • Arrange for equality tests between pointers and a constant integer 0 to check for the magic value instead (§6.5.9/6)
  • Arrange for all contexts in which a pointer type is evaluated as a boolean to check for equality to the magic value instead of checking for zero. This follows from the equality testing semantics, but the compiler may implement it differently internally. See §6.5.13/3, §6.5.14/3, §6.5.15/4, §6.5.3.3/5, §6.8.4.1/2, §6.8.5/4
  • As caf pointed out, update the semantics for initialization of static objects (§6.7.8/10) and partial compound initializers (§6.7.8/21) to reflect the new null pointer representation.
  • Create an alternate way to access true address zero.

There are some things you do not have to handle. For example:

int x = 0;
void *p = (void*)x;

After this, p is NOT guaranteed to be a null pointer. Only constant assignments need be handled (this is a good approach for accessing true address zero). Likewise:

int x = 0;
assert(x == (void*)0); // CAN BE FALSE

Also:

void *p = NULL;
int x = (int)p;

x is not guaranteed to be 0.

In short, this very condition was apparently considered by the C language committee, and considerations made for those who would choose an alternate representation for NULL. All you have to do now is make major changes to your compiler, and hey presto you're done :)

As a side note, it may be possible to implement these changes with a source code transformation stage before the compiler proper. That is, instead of the normal flow of preprocessor -> compiler -> assembler -> linker, you'd add a preprocessor -> NULL transformation -> compiler -> assembler -> linker. Then you could do transformations like:

p = 0;
if (p) { ... }
/* becomes */
p = (void*)-1;
if ((void*)(p) != (void*)(-1)) { ... }

This would require a full C parser, as well as a type parser and analysis of typedefs and variable declarations to determine which identifiers correspond to pointers. However, by doing this you could avoid having to make changes to the code generation portions of the compiler proper. clang may be useful for implementing this - I understand it was designed with transformations like this in mind. You would still likely need to make changes to the standard library as well of course.

Is C open source?

53 votes

This is probably a stupid question, but I've been wondering about this for a while. Does C (or any other low-level language, for that matter) even have source, or is the compiler the part that "does all the work", including parsing? If so, couldn't different compilers have different C dialects? Where does the stdlib factor into this? I would really like to know how this works.

The C language is not a piece of software but a defined standard, so one wouldn't say that it's open-source, but rather that it's an open standard.

There are a gazillion different compilers for C however, and many of those are indeed open-source. The most notable example is GCC's C compiler, which is all under the GNU General Public License (GPL), an open-source license.

There are more options. Watcom is open-source, for instance. There is no shortage of open-source C compilers, but without a doubt the most widespread one, at least in the non-Windows world, is GCC.

For Windows, your best bet is probably Watcom or GCC by using Cygwin or MinGW.

For statement in C

38 votes

Possible Duplicate: Help with C puzzle

This morning i had a job interview and they gave me this problem:

You should change one character to print "*" 42 times. You can replace, add or remove ONLY one character.

Still i cant figured it, i've tried over and over again.

#include <stdio.h>
main(){
    int i,n = 42;

   for(i = 0; i < n; i--){
       printf("*");
   }
}

#include <stdio.h>
main(){
    int i,n = 42;

   for(i = 0; -i < n; i--){    //added a minus here
       printf("*");
   }
}

But to be honest, I think that this is a silly interview question.

"int main (vooid)"? How does that work?

31 votes

I recently had to type in a small C test program and, in the process, I made a spelling mistake in the main function by accidentally using vooid instead of void.

And yet it still worked.

Reducing it down to its smallest complete version, I ended up with:

int main (vooid) {
    return 42;
}

This does indeed compile (gcc -Wall -o myprog myprog.c) andm when run, it returns 42.

How exactly is this valid code?


Here's a transcript cut and pasted from my bash shell to show what I'm doing:

pax$ cat qq.c
int main (vooid) {
    return 42;
}

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq

pax$ echo $?
42

Isn't it just using "old-style" function-declaration syntax; you're implicitly declaring an int parameter called vooid?

What does it mean for a data structure to be "intrusive"?

22 votes

I've seen the term intrusive used to describe data structures like lists and stacks, but what does it mean?

Can you give a code example of an intrusive data structure, and how it differs from a non-intrusive one?

Also, why make it intrusive (or, non-intrusive)? What are the benefits? What are the disadvantages?

An intrusive data structure is one that requires help from the elements it intends to store in order to store them.

Let me reword that. When you put something into that data structure, that "something" becomes aware of the fact that it is in that data structure, in some way. Adding the element to the data structure changes the element.

For instance, you can build a non-intrusive binary tree, where each node have a reference to the left and right sub-trees, and a reference to the element value of that node.

Or, you can build an intrusive one where the references to those sub-trees are embedded into the value itself.

An example of an intrusive data structure would be an ordered list of elements that are mutable. If the element changes, the list needs to be reordered, so the list object has to intrude on the privacy of the elements in order to get their cooperation. ie. the element has to know about the list it is in, and inform it of changes.

ORM-systems usually revolve around intrusive data structures, to minimize iteration over large lists of objects. For instance, if you retrieve a list of all the employees in the database, then change the name of one of them, and want to save it back to the database, the intrusive list of employees would be told when the employee object changed because that object knows which list it is in.

A non-intrusive list would not be told, and would have to figure out what changed and how it changed by itself.

What kind of operations might one need to do before main()

18 votes

I came across this question asking how to execute code before main() in C, mentioning there were strategies for C++. I've mostly lived in application space, so executing before main() has never occurred to me. What kind of things require this technique?

"What kind of things require this technique?"

Point of fact: none.

However, there are a lot of useful things you might WANT to do before main for a variety of reasons. For just one practical example, say you have an abstract factory that builds doohickies. You could make sure to build the factory instance, assign it to some special area, and then register the various concrete doohickies to it...yes, you can do that.

On the other hand, if you implement the factory as a singleton and use the facts of global value initialization to "trick" the implementation into registering concrete doohickies before main starts you gain several benefits with very few costs (the fact of using singletons, basically a non-issue here, is pretty much the only one).

For example you:

  1. Don't have to maintain a list of registrations that all must be explicitly called. In fact, you can even declare and define an entire class in private scope, out of sight of anyone, and have it available for use when the program starts.

  2. main() doesn't have to do a bunch of crap with a bunch of objects it doesn't care about.

So, none of this is actually necessary. However, you can reduce coupling and maintenance issues if you leverage the fact that globals are initialized before main begins.

Multiply by 0 optimization.

16 votes

Suppose i have:

double f(const double *r) {
    return 0*(r[0]*r[1]);
}

should compiler be able to optimize out the segment, or does it still have to perform operation, in case the values might be inf or nan?

gcc -O3 -S test.c:

        .file   "test.c"
        .text
        .p2align 4,,15
.globl f
        .type   f, @function
f:
.LFB0:
        .cfi_startproc
        movsd   (%rdi), %xmm0
        mulsd   8(%rdi), %xmm0
        mulsd   .LC0(%rip), %xmm0
        ret
        .cfi_endproc
.LFE0:
        .size   f, .-f
        .section        .rodata.cst8,"aM",@progbits,8
        .align 8
.LC0:
        .long   0
        .long   0
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

seems no elimination?

aha:

gcc -O3  -ffast-math  -S test.c

        .file   "test.c"
        .text
        .p2align 4,,15
.globl f
        .type   f, @function
f:
.LFB0:
        .cfi_startproc
        xorpd   %xmm0, %xmm0
        ret
        .cfi_endproc
.LFE0:
        .size   f, .-f
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

It isn't only inf and NaN that prevent the optimization there, it's also the sign - 0.0 * something negative is -0.0, otherwise it's 0.0, so you actually have to compute the sign of r[0]*r[1].

What's the point of const void?

16 votes

Apparently, it is possible to declare a function returning const void:

const void foo()
{
}

g++ seems to consider the const important, because the following code does not compile:

#include <type_traits>

static_assert(std::is_same<void(), const void()>::value, "const matters");

So does const void have any practical significance?

Not really. But to ignore cv-qualifications on void or to make them errors could create unnecessary complexity in terms of both compiler implementation and end-user code. Consider templates like

  template<typename T>
  const T ...

There's no reason to make using void in that scenario a special case (more than it already is), it would just create headaches.

Also, while const void isn't helpful, const void* has its uses.

Correct Term for "..."

15 votes

Consider printf:

int printf ( const char * format, ... );

What are the terms used to describe the ... and the functions that use it? I've been calling it an ellipsis, but that's like calling & the "ampersand operator."

Variable length parameter list

Edit:

Or, if describing the function itself: Variadic function

Why a variable can't be defined twice in 2 files in C..

14 votes

Hi,

Why can't I have int a; in 2 C files. I intend to combine both to make executable. I know from experience that I can't, but I want to find where the standard C99 says this and seal my understanding.

I am reading ISO C99 standard from http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf. It says on page 42:

6.2.2 Linkages of identifiers

1 An identifier declared in different scopes or in the same scope more than once can be made to refer to the same object or function by a process called linkage.There are three kinds of linkage: external, internal, and none.

2 In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.

3 If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static,the identifier has internal linkage.

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

5 If the declaration of an identifier for a function has no storage-class specifier,its linkage is determined exactly as if it were declared with the storage-class specifier extern.If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.


After reading this it looks that if I declare a variable like say int a; in 2 source files. then both have external linkage as per rule 5 and 4. and then as per rule 2, both should refer to the same object. Then why does the compiler create problem. Where in the standard it is hinted that we can't declare like this in 2 source files and this should throw compilation error. Firstly, where in the standard, it says that int a is a definition, and then where it says that 2 instances of definitions are not acceptable. I know that it is not allowed from my experience, but it would be very useful to me, if I can find this in the standard and seal my understanding.

Do the following excerpts from the standard in combination amount to this rule? or I have missed that glue? :


A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that: —for an object, causes storage to be reserved for that object; —for a function, includes the function body; —for an enumeration constant or typedef name, is the (only) declaration of the identifier.

As discussed in 5.1.1.1, the unit of program text after preprocessing is a translation unit, which consists of a sequence of external declarations. These are described as ‘‘external’’ because theyappear outside anyfunction (and hence have file scope). As discussed in 6.7, a declaration that also causes storage to be reserved for an object or a function named by the identifier is a definition.

An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.


Thanks.

I think you need 6.9.2/2:

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

and 6.9/5:

An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.

Basically, int a; is a tentative definition. You can have multiple tentative definitions in a single translation unit but the effect is the same as having one non-tentative external definition (e.g. something like int a = 0;). Having more that one definition of an object with external linkage in a program is a violation of 6.9/5.

Note that it is a "common extension" to allow more than one external definitions of an object so long as at most only one is initialized and the definitions agree (see J.5.11).

sizeof(""+0) != sizeof(char *) Bug or undefined behaviour?

13 votes

The following C program:

#include <stdio.h>

int main(void)
{
    printf("%u %u %u\n",sizeof "",sizeof(""+0),sizeof(char *));
    return 0;
}

outputs 1 4 4 when compiled with GCC on Linux, but outputs 1 1 4 when compiled with Microsoft Visual C++ on Windows. The GCC result is what I would expect. Do they differ because MSVC has a bug or because sizeof(""+0) is undefined? For both compilers the behaviour (i.e. whether the middle value printed is equal to the first value or the last value) is the same no matter what string literal or integer constant you use.

A relevant reference in the ANSI C Standard seems to be 6.2.2.1 - Lvalues and function designators:

"Except when it is the operand of the sizeof operator ... an lvalue that has type 'array of type' is converted to an expression that has type 'pointer to type' that points to the initial element of the array object and is not an lvalue".

Here though the "Except" should not apply because in sizeof(""+0) the array/string literal is an operand of + not sizeof.

Because "fooabc" is of type char[7], sizeof("fooabc") yields the same as sizeof(char[7]). However, arrays can be implicitly converted - the part you quoted - to pointers (some people wrongly call this "decay"), and since this is necessary for the arithmetic (+) to work, ""+0 will have a type of char*. And a char pointer can have a different size than the array. In that regard, MSVC's behavior seems broken.

Convert a maximum heap to a binary search tree.

13 votes

We are given an array of 2m - 1 distinct, comparable elements, indexed starting from 1.

We can view the array as a complete binary tree:

Node is placed at index i.
Left child is placed at 2i.
Right child is placed at 2i+1.

For instance, the array

[7 6 4 5 2 3 1]

is the tree

       7
    /    \
   6       4
  /  \    / \
 5    2   3  1 

Now when viewed as a binary tree, these elements satisfy the heap property, a node is greater than both its children:

A[i] > A[2i] and A[i] > A[2i+1]

Are there reasonably fast, in-place algorithm to shuffle the elements of the array around so that the resulting binary tree (as described above) is a binary search tree?

Recall that in a binary search tree, a node is greater than all its left descendants, and less than all its right descendants.

For instance the reshuffle of the above array would be

[4 2 6 1 3 5 7]

which corresponds to the binary search tree

       4
    /    \
   2       6
  /  \    / \
 1    3   5  7 

First we note that we can -- without loss of generality -- assume that we have the elements 1,2,3,... 2^m-1 in our binary tree. So, from now on, we assume that we have these numbers.

Then, my attempt would be some function to convert a sorted array (i.e. 1 2 3 4 5) into an array representing a sorted binary tree.

In a sorted binary tree with (2^m)-1 elements we have always that the "bottom" of the tree consists of all the uneven numbers, e.g. for m=3:

     4
  2     6
 1 3   5 7

This means, in the corresponding array, we have that the last numbers are all the uneven numbers:

4 2 6 1 3 5 7
      -------
         ^
         uneven numbers!

So we can construct the last "row" of the binary tree by ensuring that the last 2^(m-1) numbers in the corresponding array are all the uneven numbers. So all we need to do for the last row is to construct a function that moves all elements at positions with uneven indices to the last row.

So let us for now assume that we have a routine that -- given a sorted array as input -- establishes the last row correctly.

Then we can call the routine for the whole array to construct the last row while all other elements stay sorted. When we apply this routine on the array 1 2 3 4 5 6 7, we have the following situation:

2 4 6 1 3 5 7
      -------
         ^
         correct!

After the first round, we apply the routine for the remaining subarray (namely 2 4 6) which constructs the second last "row" of our binary tree, while we leave the remaining elements unchanged, so we get the following:

 now correct as well!
   v
  ---
4 2 6 1 3 5 7
      -------
         ^
         correct from run before

So all we have to do is to construct a function that installs the last row (i.e. the second half of the array) correctly!

This can be done in O(n log n) where n is the input size of the array. Therefore, we just traverse the array from end to the beginning and exchange the uneven positions in such a way that the last row (i.e. the latter half of the array) is correct. This can be done in-place. Afterwards, we sort the first half of the array (using e.g. heapsort). So the whole runtime of this subroutine is O(n log n).

So the runtime for an array of size n in total is:

O(n log n) + O(n/2 log n/2) + O(n/4 log n/4) + ... which is the same as O(n log n). Note that we have to use a in-place sorting algorithm such as Heapsort so that this whole stuff works completely in-place.

I'm sorry that I can't elaborate it further, but I think you can get the idea.

Can -std=c99 prevent my #includes from working properly?

11 votes

I am trying to compile a C program on a Linux system. I have an #include statement for stdlib.h.

When I compile the program with gcc as follows:

gcc -std=c99 -g -o progfoo progfoo.c progbar.c

I get warnings about Implicit declaration of function [srand48, drand48, bzero, or close].

Compiling instead as:

gcc -g -o progfoo progfoo.c progbar.c

doesn't give me the warnings, but it does yell about my use of for loops (which was the rationale for adding -std=c99 in the first place).

Given that man srand48 mentions including <stdlib.h>, which I have, I'm unsure what else the problem could be. The for loops aren't essential to anything (they were just to save time in initializing an array) so I have no problem removing them, but before I do I'd like to confirm whether the c99 standard is superseding some aspect of my #include statements.

I'm using gcc 4.1.2-50 (Red Hat).

Can -std=c99 prevent my #includes from working properly?

No, but they may show up limitations in your knowledge of how they work :-)


While the functions [sd]rand48 have a prototype in stdlib.h, they're inside an #ifdef, at least on my system:

#if defined __USE_SVID || defined __USE_XOPEN

So you will probably have to explicitly set one of those macros.

However, before you try it, be aware that it doesn't work. That's because all this stuff is controlled with gcc's feature test macros.

There's a very complicated set of rules used to set specific features on or off in features.h and the macros created there control what the header files include and exclude. The __USE_* variants are cleared and set in that header file based on other macros provided by yourself.

For example, to get __USE_SVID set so you can use srand48, you need to provide the compiler with a -D_SVID_SOURCE parameter.

But perhaps an easier way is to just use C99 with the GNU extensions. To do that, replace -std=c99 with -std=gnu99.

And, for bzero and close, these can be obtained from strings.h and unistd.h respectively.

I was a little confused at first as to why these compiled with -std=c99 when they have absolutely nothing to do with C99 but then I realised that flag only controls what the standard C headers give you.

Neither strings.h (note the plural name, this is not string.h) nor unistd.h are part of ISO C.

C standard addressing simplification inconsistency

11 votes

Section §6.5.3.2 "Address and indirection operators" ¶3 says (relevant section only):

The unary & operator returns the address of its operand. ... If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. ...

This means that this:

#define NUM 10
int tmp[NUM];
int *i = tmp;
printf("%ti\n", (ptrdiff_t) (&*i - i) );
printf("%ti\n", (ptrdiff_t) (&i[NUM] - i) );

Should be perfectly legal, printing 0 and the NUM (10). The standard seems very clear that both of those cases are required to be optimized.

However, it doesn't seem to require the following to be optimized:

struct { int a; short b; } tmp, *s = tmp;
printf("%ti\n", (ptrdiff_t) (&s->b - s) );

This seems awfully inconsistent. I can see no reason that the above code shouldn't print the sizeof(int) plus (unlikely) padding (possibly 4).

Simplifying a &-> expression is going to be the same conceptually (IMHO) as &[], a simple address-plus-offset. It's even an offset that's going to be determinable at compile time, rather than potentially runtime with the [] operator.

Is there anything in the rationale about why this is so seemingly inconsistent?

In your example, &i[10] is actually not legal: it becomes i + 10, which becomes NULL + 10, and you can't perform arithmetic on a null pointer. (6.5.6/8 lists the conditions under which pointer arithmetic can be performed)

Anyway, this rule was added in C99; it was not present in C89. My understanding is that it was added in large part to make code like the following well-defined:

int* begin, * end;
int v[10];

begin = &v[0];
end = &v[10];

That last line is technically invalid in C89 (and in C++) but is allowed in C99 because of this rule. It was a relatively minor change that made a commonly used construct well-defined.

Because you can't perform arithmetic on a null pointer, your example (&s->b) would be invalid anyway.

As for why there is this "inconsistency," I can only guess. It's likely that no one thought to make it consistent or no one saw a compelling use case for this. It's possible that this was considered and ultimately rejected. There are no remarks about the &* reduction in the Rationale. You might be able to find some definitive information in the WG14 papers, but unfortunately they seem to be quite poorly organized, so trawling through them may be tedious.

What does "cdecl" stand for?

11 votes

Yes, I know that "cdecl" is the name of a prominent calling convention, so please don't explain calling conventions to me. What I'm asking is what the abbreviation (?) "cdecl" actually stands for. I think it's a poor naming choice, because at first sight it reminds one of "C declarator" (a rather unique syntactic aspect of C). In fact, there is a program called cdecl whose sole purpose is to decipher C declarators. But the C declarator syntax has absolutely nothing to do with calling conventions as far as I can tell.

Simplified version: "stdcall" stands for "standard calling convention". What does "cdecl" stand for?

You're reading too much into this. It stands for the calling convention of the implementation for calling C functions in general (but especially important with varargs).

It doesn't have to be an abbreviation for something that combines "C" and "declaration"; names are just names, especially in programming. Mnemonics help, but even though "malloc" means "allocate memory", it has additional meaning that we know and attach to it; "alloca" also "allocates memory", for example.

Or take "struct" which "means" a "structure", but "structure" is so generic by itself that without the meaning we attach subconsciously to "struct" we would be hopelessly lost – as new programmers still learning the terminology are often lost.

How to force GCC to put constants in memory instead of generating them?

11 votes

Hello,

I have a lot of constant arrays defined in several functions. Something like the following:

const float values[4] = {-4312.435f,  -432.44333f,  4.798, 7898.89};

After inspecting gcc assembler output I noticed that these constants are generated on each run of the functions. That's quite inefficient. I suspect that this is because C/C++ spec says that even if data is const, the compiler can't assume it won't be modified (e.g. through const_cast). Is it possible to force gcc think otherwise?

I want to keep these constants defined inside the bodies of the functions, because they are quite complex. Keeping constants near where they're used helps with the maintainability a lot.

EDIT

Unfortunatelly, even when the constants are defined static, they are regenerated on the each run. I use -O3 if that helps.

EDIT2

Ok, sorry regarding the first edit, I need to investigate further. It seems that particular setup previously somehow didn't allow gcc to initialize the constants without regenerating them.

EDIT3

The problem was in my testcase, where I defined two arrays nearby, but one of them was intended to be generated. The assembler then misled me. Sorry again & thanks!

Declare them with the static keyword.

Edit: responding to your comment so I can show you some code:

This is the expected behavior. Are you doing or seeing something different?

$ cat foo.c++
int main(void)
{
    static const float foos[] = {1.234f, 5.678f, 9.012f};
    return 0;
}
$ g++ -S foo.c++
$ cat foo.s
    .file   "foo.c++"
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .section    .rodata
    .align 4
    .type   _ZZ4mainE4foos, @object
    .size   _ZZ4mainE4foos, 12
_ZZ4mainE4foos:
    .long   1067316150
    .long   1085649453
    .long   1091580199
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits

__FILE__ In .h what does it resolve to

11 votes

Is there a specification on how the __FILE__ macro will be expanded if it is in a .h?

If I define in foo.h

#define MYFILE __FILE__

And include it in foo.c

#includes "foo.h"

void main(){
  printf("%s",MYFILE);
  ....

Does this output foo.h or foo.c? (Yes I realize this is a stupid example)

Sorry for what should be a simple question. The documentation on the web seems conflicting. For what it is worth VS2008 comes back as foo.c which is what I would expect....I think. I am just trying to confirm if this is defined behavior.

The advice given in the accepted answer is 'generally correct'. However, it is not absolutely correct - and here is the counter-example:

$ cat x.h
static void helper(void)
{
    printf("%s:%d helper\n", __FILE__, __LINE__);
}
$ cat x.c
#include <stdio.h>
#include "x.h"

int main(void)
{
    helper();
    printf("%s:%d\n", __FILE__, __LINE__);
    return 0;
}

$ make x
cc -Wall -Wextra -std=c99 -g x.c -o x
$ ./x
x.h:3 helper
x.c:7
$

This is a contrived example; in C, you very seldom put actual code into a header as I did here. But the output shows that there are circumstances where the name of the header can be the correct name that __FILE__ expands to.

In C, if B is volatile, should the expression (void)(B = 1) read B

11 votes

I work on compilers for a couple of embedded platforms. A user has recently complained about the following behaviour from one of our compilers. Given code like this:

extern volatile int MY_REGISTER;

void Test(void)
{
    (void) (MY_REGISTER = 1);
}

The compiler generates this (in pseudo-assembler):

Test:
    move regA, 1
    store regA, MY_REGISTER
    load regB, MY_REGISER

That is, it not only writes to MY_REGISTER, but reads it back afterwards. The extra load upset him for performance reasons. I explained that this was because according to the standard "An assignment expression has the value of the left operand after the assignment, [...]".

Strangely, removing the cast-to-void changes the behaviour: the load disappears. The user's happy, but I'm just confused.

So I also checked this out in a couple of versions of GCC (3.3 and 4.4). There, the compiler never generates a load, even if the value is explicitly used, e.g.

int TestTwo(void)
{
    return (MY_REGISTER = 1);
}

Turns into

TestTwo:
    move regA, 1
    store regA, MY_REGISTER
    move returnValue, 1
    return

Does anyone have a view on which is a correct interpretation of the standard? Should the read-back happen at all? Is it correct or useful to add the read only if the value is used or cast to void?

The relevant paragraph in the standard is this

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. The type of an assignment expression is the type of the left operand unless the left operand has qualified type, in which case it is the unqualified version of the type of the left operand. The side effect of updating the stored value of the left operand shall occur between the previous and the next sequence point.

So this clearly makes the difference between "the value of the left operand" and the update of the stored value. Also note that the return is not an lvalue (so there is no reference to the variable in the return of the expression) and all qualifiers are lost.

So I read this as gcc doing the right thing when it returns the value that it knowingly has to store.

Edit:

The upcoming standard plans to clarify that by adding a footnote:

The implementation is permitted to read the object to determine the value but is not required to, even when the object has volatile-qualified type.

Edit 2:

Actually there is another paragraph about expression statements that might shed a light on that:

The expression in an expression statement is evaluated as a void expression for its side effects.\footnote{Such as assignments, and function calls which have side effects}

Since this implies that the effect of returning a value is not wanted for such a statement, this strongly suggests that the value may only be loaded from the variable if the value is used.

As a summary, your customer really is rightly upset when he sees that the variable is loaded. This behavior might be in accordance with the standard if you stretch the interpretation of it, but it clearly is on the borderline of being acceptable.

Linux-x64 glibc: Why does Feb 1 come before Jan 31?

9 votes

When you call mktime(), Feb 1 seems to come before Jan 31. Why is this? Am I doing something wrong or is this a bug in glibc?

Here's the code:

struct tm tm;
time_t tt;

memset(&tm, 0, sizeof(tm));
tm.tm_year = 2011;
tm.tm_mon = 1;
tm.tm_mday = 31;
tm.tm_hour = 11;
tm.tm_min = 41;
tm.tm_sec = 28;
tm.tm_isdst = 0;
tt = mktime(&tm);

printf("Time now %d-%d-%d %d:%d:%d (%s) = %lu\n",
    tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_zone, tt);


memset(&tm, 0, sizeof(tm));
tm.tm_year = 2011;
tm.tm_mon = 2;
tm.tm_mday = 1;
tm.tm_hour = 1;
tm.tm_min = 1;
tm.tm_sec = 1;
tm.tm_isdst = 0;
tt = mktime(&tm);

printf("Time now %d-%d-%d %d:%d:%d (%s) = %lu\n",
    tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_zone, tt);

And here's the output:

Time now 2011-2-3 11:41:28 (PST) = 61257325288
Time now 2011-2-1 1:1:1 (PST) = 61257114061

Note that the original intention was to compare two time_t's. This issue causes the first date/time to appear to be later than the second, which is obviously a bit of a problem.

This is just compiled with "gcc test.c" and run with "./a.out" on Ubuntu 9.10, gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8), libc-2.10.1-0ubuntu15

On a 32-bit system the results are as expected - i.e. completely different to the 64 bit result!

Would anyone care to confirm/refute this result and/or give some insight into what I may be doing wrong?

tm_mon is zero-based, so you attempted to set February 31st, which got normalized. Here's a link to the definition of mktime().

Fastest method of screen capturing

8 votes

I want to write a screencasting program for the Windows platform, but am unsure of how to capture the screen. The only method I'm aware of is to use GDI, but I'm curious whether there are other ways to go about this, and, if there are, which incurs the least overhead? Speed is a priority.

The screencasting program will be for recording game footage, although, if this does narrow down the options, I'm still open for any other suggestions that fall out of this scope. Knowledge isn't bad, after all.

Edit: I came across this article: Various methods for capturing the screen. It has introduced me to the Windows Media API way of doing it and the DirectX way of doing it. Using the Windows Media API is apparently the fastest way to capture the screen out of the methods presented. It also mentions in the Conclusion that disabling hardware acceleration could drastically improve the performance of the capture application. I'm curious as to why this is. Could anyone fill in the missing blanks for me?

Edit: I read that screencasting programs such as Camtasia use their own capture driver. Could someone give me an in-depth explanation on how it works, and why it is faster? I may also need guidance on implementing something like that, but I'm sure there is existing documentation anyway.

Also, I now know how FRAPS records the screen. It hooks the underlying graphics API to read from the back buffer. From what I understand, this is faster than reading from the front buffer, because you are reading from system RAM, rather than video RAM. You can read the article here.

This is what I use to collect single frames, but if you modify this and keep the two targets open all the time then you could "stream" it to disk using a static counter for the file name. - I can't recall where I found this, but it has been modified, thanks to whoever!

void dump_buffer()
{
   IDirect3DSurface9* pRenderTarget=NULL;
   IDirect3DSurface9* pDestTarget=NULL;
     const char file[] = "Pickture.bmp";
   // sanity checks.
   if (Device == NULL)
      return;

   // get the render target surface.
   HRESULT hr = Device->GetRenderTarget(0, &pRenderTarget);
   // get the current adapter display mode.
   //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);

   // create a destination surface.
   hr = Device->CreateOffscreenPlainSurface(DisplayMde.Width,
                         DisplayMde.Height,
                         DisplayMde.Format,
                         D3DPOOL_SYSTEMMEM,
                         &pDestTarget,
                         NULL);
   //copy the render target to the destination surface.
   hr = Device->GetRenderTargetData(pRenderTarget, pDestTarget);
   //save its contents to a bitmap file.
   hr = D3DXSaveSurfaceToFile(file,
                              D3DXIFF_BMP,
                              pDestTarget,
                              NULL,
                              NULL);

   // clean up.
   pRenderTarget->Release();
   pDestTarget->Release();
}