I am using Isabelle to verify a C program. During the verification process, I used the c-parser install-C-file to load the code, but the following issue occurred:
attempt to cause decay to pointer on array without an address
The c code is as follows
void GetName(char result[32])
{
static const char cv[11] = {'m','a','i','n','_','t','h','r','e','a','d'};
long b_i;
long i;
for (i = 0; i < 32; i++) {
result[i] = '\0';
}
i = 1;
for (b_i = 0; b_i < 11; b_i++) {
i = b_i + 1;
result[b_i] = cv[b_i];
}
result[i] = '\0';
}
typedef struct Attribute {
char name[32];
} Attribute;
void PartitionInit() {
Attribute a;
GetName(a.name);
}
The line of code that caused the error is GetName(a.name);
How can I make install-C-file load this file properly?
The error message in Isabelle is as follows.
1704726218: Added external decl for SetDiff with 3 args.
1704726218: Added external decl for GLOBAL Init with 0 args.
1704726218: Added external decl for GetProcessIndex with 2 args.
1704726218: Added external decl for SYS CREATE PROCESS with 4 args.
1704726218: Translating function Partition Init
/home/xxx/formal-c/Partition Init.c:43.10-43.24: Attempting to cause decay to pointer on array without an address
The diagnostic is indeed surprising: function
GetName
is defined as taking a pointer tochar
as an argument and you are passing an array ofchar
which decays to a pointer to its first element. No problem at all. The prototypevoid GetName(char result[32])
is equivalent tovoid GetName(char *result)
and the callGetName(a.name)
is equivalent toGetName(&a.name[0])
.The diagnostic wording is incorrect too: passing
a.name
effectively causes decay to pointer of the arraya.name
, but this array does have an address asa
has been defined as a local object with automatic storage. The objecta
is instantiated by the compiler upon entering the function body and the address ofa.name
is the same as that ofa
itself. No bug there.The array length
32
in the prototype is meaningless, it is ignored. Specifying a length in the prototype is confusing and may indicate a misconception by the programmer. C99 introduced a new syntax to specify a minimum length of the array pointed to by a pointer received as an argument, which might be what the programmer intended to convey. The syntax isIsabelle might be complaining about this potential confusion, but the diagnostic is incomprehensible,
You can try these modifications to see where Isabelle's confusion comes from:
try changing the prototype of
GetName
totry changing the prototype of
GetName
totry changing the prototype of
GetName
towhich is not equivalent to the posted one but more consistent with the requirement that
result
point to an array of at least 32 bytes.try intializing the
Attribute
object inPartitionInit
: