why can't array forward declarations be static?



An array can be declared and used without the size being known, as long as
it's fully defined with a size in some other source file:

$ cat a.c
cat: a.c: No such file or directory
$ cd /tmp
$ cat a.c
extern int foo[];
int get_foo(int x)
{
return foo[x];
}
$ cat b.c
int foo[100];
int main(void) { }
$ gcc -std=c99 -pedantic -Wall a.c b.c
$

The full definition can also come later in the same source file:

$ cat ab.c
extern int foo[];
int get_foo(int x)
{
return foo[x];
}
int foo[100];
int main(void) { }
$ gcc -std=c99 -pedantic -Wall ab.c
$

What if you don't want it to be exported?

$ cat ab_static.c
static int foo[];
int get_foo(int x)
{
return foo[x];
}
static int foo[100];
int main(void) { }
$ gcc -std=c99 -pedantic -Wall ab_static.c
ab_static.c:1: error: array size missing in 'foo'
ab_static.c:6: error: conflicting types for 'foo'
ab_static.c:1: error: previous declaration of 'foo' was here
$

Oops. But look at this:

$ gcc -std=c99 -Wall ab_static.c
$

Without -pedantic, not an error, not even a warning. That means gcc believes
that the forward declaration with static is perfectly reasonable although
technically forbidden by the standard. I agree that it's perfectly
reasonable, so now I come to my point: why is this forbidden?

Sighting in the wild: this is the only thing preventing ffmpeg from being
compilable with -pedantic. The array is an array of structs, it's initialized
using a size implicitly defined by the length of the initializer, each struct
contains a function pointer that's initialized to point to a static function
that's declared after the array's forward declaration, and all these
functions use the array.

So there's really no way to rearrange it to eliminate the forward declaration
without adding a lot more forward declarations of static functions, or
manually counting the array elements to provide a size in the array forward
declaration. This is the best possible organization of the code. It really
seems weird that the only way to make it pedantically correct is to make
something extern that isn't used in another source file.

--
Defiantly on topic,
Alan Curry
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • Re: How do I create a function in my library for passing user callback function
    ... int my_callback_return; ... matches the declaration in the header file: ... in your source file, as well as any other functions that you have ... I'm surprised the compiler didn't get more upset. ...
    (comp.lang.c)
  • Re: Finding a perfect number.
    ... That's really an algorithm question, ... several numbers you expect to use to populate the array in step 3. ... int number, i, split, total; ... declaration of arrays with a length which is dynamically determined. ...
    (comp.lang.c)
  • Re: Implicit int
    ... compile or implement, or even would have been in the 1970s. ... note that if you can't declare an array of size "n", ... could not already do with long int, had they chosen so to do. ... I recognise that this is not a popular view, but if the declaration is ...
    (comp.std.c)
  • Re: More proof of errors going uncorrected among the "regs"
    ... of a declaration of an object with incomplete type. ... I've worked with code that had an array declared like that. ... unit containing `int array;' at file scope and with no ...
    (comp.lang.c)
  • Re: Another C# marshaling question
    ... You will also have to change your function declaration to: ... public static extern int FF_Function( ... Then, what you have to do on return is marshal the array, like so: ... > public class FF_AO_OrderList ...
    (microsoft.public.dotnet.languages.csharp)