This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

sscanf causes multiple public definitions of getchar

When I try to use sscanf in my application, I get the error:

linking...
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: GETCHAR MODULE: C:\KEIL\C51\LIB\C51L.LIB (GETCHAR)
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?GETCHAR?GETCHAR
*** ERROR L118: REFERENCE MADE TO ERRONEOUS EXTERNAL SYMBOL: GETCHAR MODULE: C:\KEIL\C51\LIB\C51FPL.LIB (SCANF) ADDRESS: 1EF6H

I have a custom version of getchar in my program that
calls an interrupt driven serial I/O handler.

Since sscanf does not use serial I/O why is it trying to use scanf or even getchar for that matter.

How do I use a custom getchar function and sscanf in the same program?

Parents
  • I'm hypothesising a bit here:

    Do scanf() and sscanf() exist in seperate segments in the library? C51 seems to track references segment-to-segment, not symbol-to-symbol. So, if scanf() and sscanf() live together, and scanf() references getchar, then SegmentOf(scanf) == SegmentOf(sscanf) references SegmentOf(getchar). Including sscanf() thus creates a useless reference to getchar(), even though sscanf() itself does not directly cause this problem.

    When this happens in user code, the usual advice you get is to break up the .c file into several. For library code, you can't do this of course.

    This useless reference would be ignored, except that before the toolchain gets that far, it's running into the problem that it can see two getchar()s with different public definitions. It prints the error for this problem before it gets around to realizing that the one of the two references to getchar() would go away later.

    So, if you follow the suggestion in the linked thread, and make the function prototypes of both versions of getchar(), library and custom, the same, you'd get past this error. The linker would then later eliminate the unneeded reference (particularly with the dead code elimination option introduced in v7.50. Thanks, Keil!)

    (IMO, the function signature for a customized replacement would logically be the same in any event. If the function really needs different arguments, then call it something other than "getchar" to avoid confusion with the standard function.)

Reply
  • I'm hypothesising a bit here:

    Do scanf() and sscanf() exist in seperate segments in the library? C51 seems to track references segment-to-segment, not symbol-to-symbol. So, if scanf() and sscanf() live together, and scanf() references getchar, then SegmentOf(scanf) == SegmentOf(sscanf) references SegmentOf(getchar). Including sscanf() thus creates a useless reference to getchar(), even though sscanf() itself does not directly cause this problem.

    When this happens in user code, the usual advice you get is to break up the .c file into several. For library code, you can't do this of course.

    This useless reference would be ignored, except that before the toolchain gets that far, it's running into the problem that it can see two getchar()s with different public definitions. It prints the error for this problem before it gets around to realizing that the one of the two references to getchar() would go away later.

    So, if you follow the suggestion in the linked thread, and make the function prototypes of both versions of getchar(), library and custom, the same, you'd get past this error. The linker would then later eliminate the unneeded reference (particularly with the dead code elimination option introduced in v7.50. Thanks, Keil!)

    (IMO, the function signature for a customized replacement would logically be the same in any event. If the function really needs different arguments, then call it something other than "getchar" to avoid confusion with the standard function.)

Children