Question

UPDATE

The original description below has many errors; gawk lint does not complain about uninitialized arrays used as RHS of in. For example, the following example gives no errors or warnings. I am not deleting the question because the answer I am about to accept gives good suggestion of using split with an empty string to create an empty array.

BEGIN{
    LINT = "fatal"; 
    // print x; // LINT gives error if this is uncommented 
    thread = 0;
    if (thread in threads_start) { 
        print "if"; 
    } else {  
        print "not if"; 
    }
}

Original Question

A lot of my awk scripts have a construct as follows:

if (thread in threads_start) {  // LINT warning here
  printf("%s started at %d\n", threads[thread_start]));
} else {
  printf("%s started at unknown\n");
}

With gawk --lint which results in

warning: reference to uninitialized variable `thread_start'

So I initialize in the BEGIN block as follows. But this looks kludge-y. Is there a more elegant way to create a zero-element array?

BEGIN { LINT = 1; thread_start[0] = 0; delete thread_start[0]; }
Was it helpful?

Solution

Summary

The idiomatic method of creating an empty array in Awk is to use split().

Details

To simplify your example above to focus on your question rather than your typos, the fatal error can be triggered with:

BEGIN{
    LINT = "fatal"; 
    if (thread in threads_start) { 
        print "if"; 
    } else {  
        print "not if"; 
    }
}

which produces the following error:

gawk: cmd. line:3: fatal: reference to uninitialized variable `thread'

Giving thread a value before using it to search in threads_start passes linting:

BEGIN{
    LINT = "fatal"; 
    thread = 0;
    if (thread in threads_start) { 
        print "if"; 
    } else {  
        print "not if"; 
    }
}

produces:

not if

To create a linting error with an uninitialised array, we need to attempt to access an non-existent entry:

BEGIN{
    LINT = "fatal"; 
    thread = 0;
    if (threads_start[thread]) { 
        print "if"; 
    } else {  
        print "not if"; 
    }
}

produces:

gawk: cmd. line:4: fatal: reference to uninitialized element `threads_start["0"]'

So, you don't really need to create an empty array in Awk, but if you want to do so, and answer your question, use split():

BEGIN{
    LINT = "fatal"; 
    thread = 0;
    split("", threads_start);
    if (thread in threads_start) { 
        print "if"; 
    } else {  
        print "not if"; 
    }
}

produces:

not if

OTHER TIPS

I think you might have made a few typo's in your code.

if (thread in threads_start) { // LINT warning here (you think)

Here you look for the index thread in array threads_start.

  printf("%s started at %d\n", threads[thread_start])); // Actual LINT warning

But here you print the index thread_start in array threads! Also notice the different s's thread/threads and threads_start/thread_start. Gawk is actually warning you correctly about the usage of thread_start (without s) on the second line.

There also is an error in your printf format.

When you change these the lint warning disappears:

if (thread in threads_start) {
  printf("%s started at %d\n", thread, threads_start[thread]));
} else {
  printf("%s started at unknown\n");
}

But perhaps I've misunderstood what your code is supposed to do. In that case, could you post a minimal self-contained code sample that produces the spurious lint warning?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top