how to create an empty array

断了今生、忘了曾经 提交于 2020-01-07 07:09:33

问题


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]; }

回答1:


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




回答2:


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?



来源:https://stackoverflow.com/questions/7822485/how-to-create-an-empty-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!