tags:

views:

69

answers:

2

I am writing a dynamically growing string buffer. I have the following in a .c file.

#ifndef STRBUF_GROWTH_SIZE
#define STRBUF_GROWTH_SIZE 4096
#endif

My code uses this constant to do the reallocation of the buffer. Now in the tests, I need to set this value to a small one so that I can check the reallocation. I tried defining this in the tests.cpp (All tests are in C++ using UnitTest++).

#define STRBUF_GROWTH_SIZE 10
TEST(StringBuffer)
{
    struct strbuf *string = strbuf_init();

    strbuf_add(string, "first");
    CHECK_EQUAL("first", string->buffer);
    CHECK_EQUAL(5, string->length);
    CHECK_EQUAL(10, string->allocated);   /* this fails */

    strbuf_add(string, " second");
    CHECK_EQUAL("first second", string->buffer);
    CHECK_EQUAL(12, string->length);
    CHECK_EQUAL(20, string->allocated); /* this fails */

    strbuf_destroy(string);
}

I am wondering why the value didn't change to 10? How can I workaround this problem?

Any thoughts?

+3  A: 

Preprocessing is done on a source-file-by-source-file basis (well, not quite, but it's close enough). A #define in one source file won't affect anything in another source file.

You'll either need to #define this in a header, which you can swap out with another header during testing, or you'll need to parameterise your library (e.g. strbuf_init(int growth_size).

Alternatively, why don't you just test with strings that are of length-4096? Then you'll be testing your actual production code.

Oli Charlesworth
Thanks. I thought about `strbuf_init(int growth_size)`. The problem with that is I need to keep the `growth_size` in a variable and using this from multiple places will overwrite this global value (this code is expected to be thread safe). BTW, keeping this value as a fields in `struct strbuf` works.
Appu
+4  A: 

The #define in your test isn't seen by your code in the other .c file. However, you can inject the macro in your build. With gcc its the -D argument. With msvc's cl its the /D argument.

paleozogt
Altho I think that having a runtime parameter (as suggested by Olie Charlesworth's answer) is probably the better way to go. Injecting the macro is good if for some reason you can't refactor the source.
paleozogt