问题
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