A useful little feature ... and statement expressions, too

Well, what do you know? I rediscovered (again) that you can, in fact,
always learn something new and useful. Being a devotee of "command
line is the only way to go", I debug using the command line interface
to dbx. Thanks to Chris Quenelle, I found a way to improve how dbx
displays line information. It's nothing earth shattering, but it sure is
nifty. Check this out:

(2) stop at "t.c":9
(dbx) r
Running: a.out
(process id 14323)
stopped in main at line 9 in file "t.c"
    9           int j = foo(1);
(dbx) li
    4   }
    5
    6   void
    7   main()
    8   {
>    9          int j = foo(1);
   10
   11           printf("j is %d\\n", j);
   12   }
(dbx)

Notice how you get source lines displayed around the breakpoint rather
than just from the line you're at forward? Nice to have that bit of
context.

Anyway, thanks to Chris for handing out this little trick in his excellent
blog. See this entry in Chris's blog for the details.


Something Coming Down The Line

"Statements and Declarations in Expressions", or more simply, just
"Statement Expressions" (also sometimes referred to as value returning
blocks), are a nice little gcc compatibility feature that extends the
utility of compound statements. Unlike compound statements, however,
statement expressions are treated just like normal expressions. This
allows arbitrarily complex code that uses such constructs as local
variables, loops, switches, and goto's, to exist within the confines of
an "expression".

So, for example, the code used inside of the statement expression below,
while admittedly contrived, is perfectly legitimate in a statement
expression.

#include <stdio.h>

void
main()
{
        int i;
        int size = 5;
        int a[5] = {1,2,3,4,5};

        i += ({
                int j;
                int maxval = 0;

                for(j=0; j<size; j++) {
                        if (a[j] > maxval) {
                                maxval = a[j];
                        }
                }
                maxval;
             });

        printf("i is %d\\n", i);
}

Notice the last statement in the statement expression above, and notice
that it is an "expression" that returns a value. The statement expression
as a whole takes on the type and associated value of this last expression.
If the last statement in a statement expression does not return a value,
then the type of the statement expression is "void" and has no value.

In general, statement expressions aren't specified directly in the source,
as is done above. Rather, they are typically used in macro definitions,
where in this context, they provide a much more flexible mechanism for
specifying desired behavior. For example, take the relatively simple case
of calculating the maximum element of an integer array, as described
above, and specify it as a macro using a statement expression:

#define MAX_ARRAY_INT(array, size)                      \\
({                                                      \\
        int i;                                          \\
        int value=0;                                    \\
                                                        \\
        for (i = 0; i < size; i++)                      \\
                if (array[i] > value) {                 \\
                        value = array[i];               \\
                }                                       \\
        value;                                          \\
})

This can then later be referenced like so:

main()
{
        int max;
        int arr[5] = {1,2,3,4,5};

        max = MAX_ARRAY_INT(arr, 5);
        printf("max is %d\\n", max);
}

There are some subtleties about statement expression usage that make
them even more useful than as described here. More next time ...

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

dpagan

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today