Diagnostic required for missing function definition?

O

Old Wolf

Does the following program require a diagnostic? Which section
of the Standard deals with this? (I read the section on function
calls and didn't see anything).

void f(void);

int main(void) { f(); }

Is the answer still the same if the function declaration was:
static void f(void);
 
R

Richard Heathfield

Old Wolf said:
Does the following program require a diagnostic? Which section
of the Standard deals with this? (I read the section on function
calls and didn't see anything).

void f(void);

int main(void) { f(); }

No diagnostic message is required. For all the compiler knows, the
definition of f() is in another translation unit. But if it isn't,
you'll get a linker error, obviously.
Is the answer still the same if the function declaration was:
static void f(void);

Excellent question. As far as I can tell, there is still no requirement
for a diagnostic message (although of course the implementation is free
to provide one if it feels like so doing), but I could easily be wrong.
 
D

Dave Vandervies

Old Wolf said:


No diagnostic message is required. For all the compiler knows, the
definition of f() is in another translation unit. But if it isn't,
you'll get a linker error, obviously.

Isn't the linker part of the implementation? So if a linker error
is required, that would mean the implementation as a whole must issue
a diagnostic.

N869 6.9 says:
[#5] An external definition is an external declaration that
is also a definition of a function or an object. If an
identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof
operator), somewhere in the entire program there shall be
exactly one external definition for the identifier;
otherwise, there shall be no more than one.127)

This is *not* in a Constraints section, so it looks to me like it's
undefined behavior and the implementation (linker in this case) is allowed
to silently accept it or silently refuse to generate an executable.

(This seems reasonable to me. Consider this source file representing
a complete program:
--------
void read(void);
int main(void) { read(); return 0; }
--------
I would be surprised to find a Unix-hosted C implementation that fails
to compile this, but the executable may or may not behave sensibly.)

Excellent question. As far as I can tell, there is still no requirement
for a diagnostic message (although of course the implementation is free
to provide one if it feels like so doing), but I could easily be wrong.

N869 6.9#3 (which *is* in a Constraints section) says:
Moreover, if an identifier declared with
internal linkage is used in an expression (other than as a
part of the operand of a sizeof operator), there shall be
exactly one external definition for the identifier in the
translation unit.

I don't think just a prototype is an "external definition" as defined
in #5, so it looks to me like using a function (or other object) that is
declared static and not defined in that translation unit is a constraint
violation.


dave
 
J

jacob.navia

Old Wolf a écrit :
Does the following program require a diagnostic? Which section
of the Standard deals with this? (I read the section on function
calls and didn't see anything).

void f(void);

int main(void) { f(); }

Is the answer still the same if the function declaration was:
static void f(void);
No diagnostic is required, as far as I see

main() has an implicit result (zero) so the absence of an explicit
result is OK.
 
R

Richard Heathfield

Dave Vandervies said:
Isn't the linker part of the implementation?

Yes - although it needn't be an integral part.
So if a linker error
is required, that would mean the implementation as a whole must issue
a diagnostic.

At the point where it realises the reference cannot be resolved, yes.
But need that point be reached? I'm vaguely thinking of a system where
function calls are bound at runtime - DLLs and the like.
N869 6.9 says:
[#5] An external definition is an external declaration that
is also a definition of a function or an object. If an
identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof
operator), somewhere in the entire program there shall be
exactly one external definition for the identifier;
otherwise, there shall be no more than one.127)

This is *not* in a Constraints section, so it looks to me like it's
undefined behavior and the implementation (linker in this case) is
allowed to silently accept it or silently refuse to generate an
executable.

I'll buy that.

<snip>

[static equivalent]
N869 6.9#3 (which *is* in a Constraints section) says:
Moreover, if an identifier declared with
internal linkage is used in an expression (other than as a
part of the operand of a sizeof operator), there shall be
exactly one external definition for the identifier in the
translation unit.

I don't think just a prototype is an "external definition" as defined
in #5, so it looks to me like using a function (or other object) that
is declared static and not defined in that translation unit is a
constraint violation.

You know your trouble, Dave? You're just not lazy enough!
 
K

Keith Thompson

jacob.navia said:
Old Wolf a écrit :
No diagnostic is required, as far as I see

main() has an implicit result (zero) so the absence of an explicit
result is OK.

I don't think the lack of a return was the issue. (The rule that
main() implicitly returns 0 is new in C99, but even in C90 falling off
the end of main() doesn' require a diatnostic; it merely returns an
undefined result (that's *not* undefined behavior) to the calling
environment.) The question was about calling a function f() that's
been declared but not defined.

Obviously such calls are legitimate for functions defined in other
translation units in the same program. Whether and when a diagnostic
is required if the function is never defined is another question (one
I'm too lazy to figure out how to answer).
 
C

CBFalconer

Old said:
Does the following program require a diagnostic? Which section
of the Standard deals with this? (I read the section on function
calls and didn't see anything).

void f(void);

int main(void) { f(); }

Is the answer still the same if the function declaration was:
static void f(void);

You don't have a function to call. You declared it, but never
defined it.
 
D

Dave Vandervies

Dave Vandervies said:

At the point where it realises the reference cannot be resolved, yes.
But need that point be reached? I'm vaguely thinking of a system where
function calls are bound at runtime - DLLs and the like.

I've never encountered a system that did runtime identifier binding
without doing a link-time pass as well to make sure that the identifiers
that were needed could be found. Of course if you try to run it
with something other than the runtime linking files that it did that
check against, it could still die with a runtime failure to do the
actual binding.

Finding a suitably named identifier somewhere else, and silently
producing unpredictable results, is also perfectly valid, at least if
I'm correct that using an identifier that you don't provide a definition
for somewhere invokes undefined behavior. This could also be caused by
shuffling dynamically linked objects around behind the implementation's
back (which is actually quite likely to be useful when done by somebody
who understands what they're getting themselves into).

You know your trouble, Dave? You're just not lazy enough!

No, the real trouble is that I can't figure out how to control under
which conditions I'm lazy enough. Especially since I usually seem to be
a lot more interested in things that are only relevant to other peoples'
questions than things I'm likely to need to know.


dave

--
Dave Vandervies (e-mail address removed)
Void pointers will automatically be converted to the right type when the
assignment is made. --Simon Biber and
Or to the wrong type, as the case may be. Kaz Kylheku in CLC
 
D

Dik T. Winter

> I've never encountered a system that did runtime identifier binding
> without doing a link-time pass as well to make sure that the identifiers
> that were needed could be found.

Well, I have encountered such a system.
 
D

Dave Vandervies

Well, I have encountered such a system.

I was fishing for something like that, but more detail would have
been nice.

Which system? To keep it on topic, did the C implementation have anything
interesting about it?


dave
 
D

Dik T. Winter

>
> I was fishing for something like that, but more detail would have
> been nice.
>
> Which system? To keep it on topic, did the C implementation have anything
> interesting about it?

CDC Cyber, NOS/BE, later incarnations. There did exist a C implementation
for it, but I never used that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top