Cracking C structure

B

Bart Torbert

For testing purposes it would be convenient to load dummy values into
a set of C structures. These structures are complex (in the sense of
a mix of data types), they are quite large (total number of elements)
and they will have a tendency to change over time.

I would be best if the dummy data was "meaningful", real dates in a
date field, a small number in the number field, a short string in a
text field, etc.

Is there a way to load the data without having to walk through each
element of each structure. I would be time consuming and fragile to
write a special function to load each structure as there are so many
and their exact content tends to change with frequent changes in the
software.

The ideal solution would be able to take a structure, loop through all
elements, for each element be able to determine its type and
dynamically assign the elment an appropriate value.

Is this doable?

Bart Torbert
(e-mail address removed)
 
E

Eric Sosman

Bart said:
For testing purposes it would be convenient to load dummy values into
a set of C structures. These structures are complex (in the sense of
a mix of data types), they are quite large (total number of elements)
and they will have a tendency to change over time.

I would be best if the dummy data was "meaningful", real dates in a
date field, a small number in the number field, a short string in a
text field, etc.

Is there a way to load the data without having to walk through each
element of each structure. I would be time consuming and fragile to
write a special function to load each structure as there are so many
and their exact content tends to change with frequent changes in the
software.

The ideal solution would be able to take a structure, loop through all
elements, for each element be able to determine its type and
dynamically assign the elment an appropriate value.

Is this doable?

No, in the sense that it is not possible to start from

struct s { int i; float f; double d; };

and somehow deduce "int, float, double."

With a little work, though, you can prepare a generic
description of a struct and write some code to process it.
You'd use something like

struct struct_layout {
enum { INT, FLOAT, DOUBLE, ..., END } type;
size_t offset;
};

struct struct_layout s_desc[] = {
{ INT, offsetof(struct s, i) },
{ FLOAT, offsetof(struct s, f) },
{ DOUBLE, offsetof(struct s, d) },
{ END, 0 }
};

You'd prepare a description like this for each struct type
of interest. Then to generate data for a particular struct
instance, you give your code a pointer to that instance and
a pointer to the matching description:

void fill_struct(void *sp, const struct struct_layout *dp);
struct s s_instance;
fill_struct (&s_instance, s_desc);

Observe that this technique is in fact more useful than
what you asked for. If "introspection" were somehow part of
C, it might at best tell you "int, float, double." But if
you prepare your own descriptions, you can go further and
tell what kinds of data these elements represent: Instead of
"int, float, double" you can have "birth_year, weight_kg,
annual_interest_rate."

In a large project it can become tedious to keep the
struct descriptions up-to-date as programmers modify the
structs themselves. If you're going to do a lot of this sort
of thing, it might be wise to generate both the struct
declarations and their corresponding definitions from a
little language invented for the purpose.
 
I

Ira Baxter

Eric Sosman said:
No, in the sense that it is not possible to start from

struct s { int i; float f; double d; };

and somehow deduce "int, float, double."

Not possible for what mechanism?
You can't do it from "inside" a conventional C program.

You *can* do it if you can process C programs like data.
If you have what amounts to a compiler front end, you *can*
loop thru struct contents; the deduction is trivial, the compiler
stores the types of the data in its symbol table.

The DMS Software Reengineering Toolkit offers a full C
parser front end with symbol table, and it could be use
to "loop thru the structure" pretty easily.

What is harder is that there is often an application constraint
on the data (e.g., the int must be in the range 0 to 5,
the sum of the float and the double must equal 2.71828),
not only in the struct, but between structs. This information
is almost never explicitly found in the code, but it is a requirement
that any test data generator honor them, or the initial conditions
for the program under test are violated and the test result
won't mean anything.

To solve that problem, somebody has to supply additional
data constraints, and then solve them during test data generation.
I'm not an expert, but I think a lot
of work has been done on test data generation with constraints.

Google for "Automated test data generation".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top