テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

(dm-lc report) removing all C90 warnings

I am making some efforts to remove all the cursing C90 warnings. In my opinion, this is as nasty as 80 col rule in Linux kernel. But, when in Rome do as the Romans do is a good choice.

Most of the warnings are acceptable except ones for designated initialization for structs as the arguments for io routines. For example, the one below is a code fragment from flush_proc routine that looping and submitting log writes to the cache device.

        while (true) {
                spin_lock_irqsave(&cache->flush_queue_lock, flags);
                while (list_empty(&cache->flush_queue)) {
                        spin_unlock_irqrestore(&cache->flush_queue_lock, flags);
                        wait_event_interruptible_timeout(
                                cache->flush_wait_queue,
                                (!list_empty(&cache->flush_queue)),
                                msecs_to_jiffies(100));
                        spin_lock_irqsave(&cache->flush_queue_lock, flags);

                        if (cache->on_terminate)
                                return;
                }

                /* Pop the first entry */
                struct flush_context *ctx;
                ctx = list_first_entry(
                        &cache->flush_queue, struct flush_context, flush_queue);
                list_del(&ctx->flush_queue);
                spin_unlock_irqrestore(&cache->flush_queue_lock, flags);

                struct segment_header *seg = ctx->seg;

                struct dm_io_request io_req = {
                        .client = lc_io_client,
                        .bi_rw = WRITE,
                        .notify.fn = NULL,
                        .mem.type = DM_IO_KMEM,
                        .mem.ptr.addr = ctx->wb->data,
                };
                struct dm_io_region region = {
                        .bdev = cache->device->bdev,
                        .sector = seg->start_sector,
                        .count = (seg->length + 1) << 3,
                };
                dm_safe_io_retry(&io_req, &region, 1, false);

This code is warned by -Wdeclaration-after-statement option flagged to gcc compiler that is by default turned on in kernel Makefile. Removing the flag from the Makefile was discussed before but rejected for the reason that traditional coding style should not be changed.
http://www.gossamer-threads.com/lists/linux/kernel/1132926

But, It is obviously meaningless to factor out flush_segment_sync routine in this context because it is clear for everyone's eyes to see that these three step codes, create two structs and put them into an io routine, submits sync io. We don't need more abstraction.

To address problem, one can wrap these three by curly braces to avoid compilation warnings but I don't think this solution will be accepted by the community. There is one having proposed this idiot solution. http://lkml.indiana.edu/hypermail/linux/kernel/0906.2/01729.html

What I am thinking of is, declaring the variables ahead and put actual value to each variable in designated initialization style with casting. To be surprised, the code below can avoid the warning,

#include <stdio.h>
struct hoge {
        int x;
};
void func(struct hoge *o)
{
        printf("%d\n", o->x);
}
int main(void){
        struct hoge o;
        printf("hogehoge\n");
        o = (struct hoge) { .x = 10 };
        func(&o);

        return 0;
}

It can not be compiled without casting at the head but can be with it. Needless to say, declaring struct hoge o after printf warns. I don't know there are codes in Linux kernel to use this trick to avoid the warnings but I will take this first and fix if pointed out. Lastly, I leaned this trick from http://stackoverflow.com/questions/330793/how-to-initialize-a-struct-in-ansi-c . Thanks for reading.