Reply by David Brown May 10, 20202020-05-10
On 09/05/2020 19:15, Tauno Voipio wrote:
> On 9.5.20 17:10, David Brown wrote: >> On 09/05/2020 00:45, Richard Damon wrote: >>> On 5/8/20 6:13 PM, David Brown wrote: >>>> On 08/05/2020 21:32, Philipp Klaus Krause wrote: >>>>> Am 08.05.20 um 20:53 schrieb Grant Edwards: >>>>>> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >>>>>>> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>>>>>>> >>>>>>>> What's the benefit of requiring extra stuff for a freestanding >>>>>>>> iplementation? >>>>>>> >>>>>>> Not requiring the users of freestanding implementations to roll >>>>>>> their >>>>>>> own implementations of that extra stuff. >>>>>> >>>>>> That's what you expect when you decide to use a freestanding >>>>>> implmentation. If I want to use an the off-the shelf memcpy() >>>>>> function, why not just link with libc? >>>>> >>>>> Which libc? >>>>> A freestanding implementation's libc might not have memcpy(). A >>>>> third-party libc might not be available for my target device. >>>>> >>>> >>>> You are worrying about a non-existent problem.&nbsp; /All/ C toolchains come >>>> with memcpy() and similar functions - certainly anything that is >>>> realistic to include in a subset of the C library for freestanding >>>> toolchains. >>>> >>>> People /never/ have to write their own memcpy() - but in freestanding >>>> systems, they can if they want to.&nbsp; (Toolchains invariably come with >>>> memcpy, but that doesn't mean they come with a memcpy implementation >>>> that is ideal for your needs.) >>>> >>> >>> But you can't call your memcpy with the name memcpy because that name is >>> RESERVED with external linkage (even if the implementation doesn't >>> support it as a freestanding implementation). >>> >>> Yes, if the implementation doesn't support a function, you can probably >>> get away with defining one of your own by that name, but it isn't >>> guaranteed that it will work. >>> >> >> Again, there is a matter of practical realities.&nbsp; Trying to define >> your own memcpy() with that same name can be risky - it's the kind of >> function that implementations treat in special ways (such as the >> compiler replacing it with inline loops).&nbsp; It is definitely a bad idea >> to make your own definitions for a function like that with semantics >> that differ from the standard version. >> >> The standard linking process used by most implementations (but not >> required by the standards) means that if you have a definition of a >> function in your C code, that will take precedence over >> implementations in the library.&nbsp; It is not unusual in embedded >> programming to use this fact to have empty stubs for functions like >> "exit" or "atexit" as a way of avoiding too much extra code being >> pulled in from the standard library. >> >> This is all highly implementation-specific, of course. > > > There's good reason to make own implementation of e.g. memcpy() in a > small embedded system: The library functions often attempt to optimize > with larger than byte transfers, and the logic is far too long for small > memory. If the implementation is in a module loaded before the standard > library, it should override the library function. It is fully OK for the > compiler to replace it with macro loops, the code simply does not refer > to the library function at all, so the point is moot here.
Yes, agreed. (But you should be aware that this only works if the implementation works the way you expect here. In practice it is likely to be fine - I have not seen any exceptions.)
> > exit(), atexit() and friends simply do not exist in a small embedded > system. The system runs forever or until power off. >
Indeed. But sometimes these get linked in by other library functions, and you can get cascades of extra library code from using a seemingly innocent little utility function. When you see your binary size suddenly much larger than you expect, the solution is sometimes to examine a map file with cross-references, figure out the root functions, and make stubs - as you say, functions like these ones will never be called, so leaving them empty is fine.
Reply by Tauno Voipio May 9, 20202020-05-09
On 9.5.20 17:10, David Brown wrote:
> On 09/05/2020 00:45, Richard Damon wrote: >> On 5/8/20 6:13 PM, David Brown wrote: >>> On 08/05/2020 21:32, Philipp Klaus Krause wrote: >>>> Am 08.05.20 um 20:53 schrieb Grant Edwards: >>>>> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >>>>>> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>>>>>> >>>>>>> What's the benefit of requiring extra stuff for a freestanding >>>>>>> iplementation? >>>>>> >>>>>> Not requiring the users of freestanding implementations to roll their >>>>>> own implementations of that extra stuff. >>>>> >>>>> That's what you expect when you decide to use a freestanding >>>>> implmentation. If I want to use an the off-the shelf memcpy() >>>>> function, why not just link with libc? >>>> >>>> Which libc? >>>> A freestanding implementation's libc might not have memcpy(). A >>>> third-party libc might not be available for my target device. >>>> >>> >>> You are worrying about a non-existent problem.&nbsp; /All/ C toolchains come >>> with memcpy() and similar functions - certainly anything that is >>> realistic to include in a subset of the C library for freestanding >>> toolchains. >>> >>> People /never/ have to write their own memcpy() - but in freestanding >>> systems, they can if they want to.&nbsp; (Toolchains invariably come with >>> memcpy, but that doesn't mean they come with a memcpy implementation >>> that is ideal for your needs.) >>> >> >> But you can't call your memcpy with the name memcpy because that name is >> RESERVED with external linkage (even if the implementation doesn't >> support it as a freestanding implementation). >> >> Yes, if the implementation doesn't support a function, you can probably >> get away with defining one of your own by that name, but it isn't >> guaranteed that it will work. >> > > Again, there is a matter of practical realities.&nbsp; Trying to define your > own memcpy() with that same name can be risky - it's the kind of > function that implementations treat in special ways (such as the > compiler replacing it with inline loops).&nbsp; It is definitely a bad idea > to make your own definitions for a function like that with semantics > that differ from the standard version. > > The standard linking process used by most implementations (but not > required by the standards) means that if you have a definition of a > function in your C code, that will take precedence over implementations > in the library.&nbsp; It is not unusual in embedded programming to use this > fact to have empty stubs for functions like "exit" or "atexit" as a way > of avoiding too much extra code being pulled in from the standard library. > > This is all highly implementation-specific, of course.
There's good reason to make own implementation of e.g. memcpy() in a small embedded system: The library functions often attempt to optimize with larger than byte transfers, and the logic is far too long for small memory. If the implementation is in a module loaded before the standard library, it should override the library function. It is fully OK for the compiler to replace it with macro loops, the code simply does not refer to the library function at all, so the point is moot here. exit(), atexit() and friends simply do not exist in a small embedded system. The system runs forever or until power off. -- -TV
Reply by David Brown May 9, 20202020-05-09
On 09/05/2020 00:45, Richard Damon wrote:
> On 5/8/20 6:13 PM, David Brown wrote: >> On 08/05/2020 21:32, Philipp Klaus Krause wrote: >>> Am 08.05.20 um 20:53 schrieb Grant Edwards: >>>> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >>>>> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>>>>> >>>>>> What's the benefit of requiring extra stuff for a freestanding >>>>>> iplementation? >>>>> >>>>> Not requiring the users of freestanding implementations to roll their >>>>> own implementations of that extra stuff. >>>> >>>> That's what you expect when you decide to use a freestanding >>>> implmentation. If I want to use an the off-the shelf memcpy() >>>> function, why not just link with libc? >>> >>> Which libc? >>> A freestanding implementation's libc might not have memcpy(). A >>> third-party libc might not be available for my target device. >>> >> >> You are worrying about a non-existent problem.&nbsp; /All/ C toolchains come >> with memcpy() and similar functions - certainly anything that is >> realistic to include in a subset of the C library for freestanding >> toolchains. >> >> People /never/ have to write their own memcpy() - but in freestanding >> systems, they can if they want to.&nbsp; (Toolchains invariably come with >> memcpy, but that doesn't mean they come with a memcpy implementation >> that is ideal for your needs.) >> > > But you can't call your memcpy with the name memcpy because that name is > RESERVED with external linkage (even if the implementation doesn't > support it as a freestanding implementation). > > Yes, if the implementation doesn't support a function, you can probably > get away with defining one of your own by that name, but it isn't > guaranteed that it will work. >
Again, there is a matter of practical realities. Trying to define your own memcpy() with that same name can be risky - it's the kind of function that implementations treat in special ways (such as the compiler replacing it with inline loops). It is definitely a bad idea to make your own definitions for a function like that with semantics that differ from the standard version. The standard linking process used by most implementations (but not required by the standards) means that if you have a definition of a function in your C code, that will take precedence over implementations in the library. It is not unusual in embedded programming to use this fact to have empty stubs for functions like "exit" or "atexit" as a way of avoiding too much extra code being pulled in from the standard library. This is all highly implementation-specific, of course.
Reply by Richard Damon May 9, 20202020-05-09
On 5/8/20 6:59 PM, Grant Edwards wrote:
> On 2020-05-08, Richard Damon <Richard@Damon-Family.org> wrote: > >> But you can't call your memcpy with the name memcpy because that name is >> RESERVED with external linkage (even if the implementation doesn't >> support it as a freestanding implementation). > > Why should I be forbidden from providing my own implementation of > memcpy()? What does such a ban accomplish? > >> Yes, if the implementation doesn't support a function, you can >> probably get away with defining one of your own by that name, but it >> isn't guaranteed that it will work. > > It should be. > > -- > Grant > >
Because of the wording of the Standard. ALL external names (like functions) defined in ANY header (independent of you using them) are reserved for the implementation with external linkage. The Standard doesn't make an exception for things not supported due to being a free-standing implementation. Part of the issue is that for a free-standing implementation you don't know (and can't really test for) that the function isn't implemented. One thing that was brought up is that maybe it would make sense to have what is and isn't defined be part of the required documentation.
Reply by Stefan Reuther May 9, 20202020-05-09
Am 08.05.2020 um 17:56 schrieb Grant Edwards:
> On 2020-05-08, Stefan Reuther <stefan.news@arcor.de> wrote: >> The point I tried to make is that there's little reason to worry >> that there is a compiler that links in all of libc if memcpy is >> used, because compilers have a means of linking these functions as >> needed. >> >> TL;DR: I don't see any technical roadblocks that would prevent >> requiring more utility functions for a freestanding implementation. > > What's the benefit of requiring extra stuff for a freestanding > iplementation?
Making the "freestanding" subset more useful. It probably depends on what one considers the mission of a freestanding implementation. I had considered the primary objective to be: run without any operating system support. Things like 'memcpy' or 'strlen', even 'sprintf', can be implemented in pure C without any operating system support (needing just a little implementation knowledge like "how to stringify a pointer" in 'sprintf', or "how to detect overlap" in 'memmove'). Therefore, adding those functions does not constrain the environment such an implementation could run on. If one instead considers a freestanding implementation to be just a portable assembler to turn logic into machine code and otherwise get out of my way, leaving out 'memcpy' & friends is plausible. Stefan
Reply by Grant Edwards May 8, 20202020-05-08
On 2020-05-08, Richard Damon <Richard@Damon-Family.org> wrote:

> But you can't call your memcpy with the name memcpy because that name is > RESERVED with external linkage (even if the implementation doesn't > support it as a freestanding implementation).
Why should I be forbidden from providing my own implementation of memcpy()? What does such a ban accomplish?
> Yes, if the implementation doesn't support a function, you can > probably get away with defining one of your own by that name, but it > isn't guaranteed that it will work.
It should be. -- Grant
Reply by Richard Damon May 8, 20202020-05-08
On 5/8/20 6:13 PM, David Brown wrote:
> On 08/05/2020 21:32, Philipp Klaus Krause wrote: >> Am 08.05.20 um 20:53 schrieb Grant Edwards: >>> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >>>> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>>>> >>>>> What's the benefit of requiring extra stuff for a freestanding >>>>> iplementation? >>>> >>>> Not requiring the users of freestanding implementations to roll their >>>> own implementations of that extra stuff. >>> >>> That's what you expect when you decide to use a freestanding >>> implmentation. If I want to use an the off-the shelf memcpy() >>> function, why not just link with libc? >> >> Which libc? >> A freestanding implementation's libc might not have memcpy(). A >> third-party libc might not be available for my target device. >> > > You are worrying about a non-existent problem.&nbsp; /All/ C toolchains come > with memcpy() and similar functions - certainly anything that is > realistic to include in a subset of the C library for freestanding > toolchains. > > People /never/ have to write their own memcpy() - but in freestanding > systems, they can if they want to.&nbsp; (Toolchains invariably come with > memcpy, but that doesn't mean they come with a memcpy implementation > that is ideal for your needs.) >
But you can't call your memcpy with the name memcpy because that name is RESERVED with external linkage (even if the implementation doesn't support it as a freestanding implementation). Yes, if the implementation doesn't support a function, you can probably get away with defining one of your own by that name, but it isn't guaranteed that it will work.
Reply by David Brown May 8, 20202020-05-08
On 08/05/2020 21:32, Philipp Klaus Krause wrote:
> Am 08.05.20 um 20:53 schrieb Grant Edwards: >> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >>> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>>> >>>> What's the benefit of requiring extra stuff for a freestanding >>>> iplementation? >>> >>> Not requiring the users of freestanding implementations to roll their >>> own implementations of that extra stuff. >> >> That's what you expect when you decide to use a freestanding >> implmentation. If I want to use an the off-the shelf memcpy() >> function, why not just link with libc? > > Which libc? > A freestanding implementation's libc might not have memcpy(). A > third-party libc might not be available for my target device. >
You are worrying about a non-existent problem. /All/ C toolchains come with memcpy() and similar functions - certainly anything that is realistic to include in a subset of the C library for freestanding toolchains. People /never/ have to write their own memcpy() - but in freestanding systems, they can if they want to. (Toolchains invariably come with memcpy, but that doesn't mean they come with a memcpy implementation that is ideal for your needs.)
Reply by Philipp Klaus Krause May 8, 20202020-05-08
Am 08.05.20 um 20:53 schrieb Grant Edwards:
> On 2020-05-08, Philipp Klaus Krause <pkk@spth.de> wrote: >> Am 08.05.20 um 17:56 schrieb Grant Edwards: >>> >>> What's the benefit of requiring extra stuff for a freestanding >>> iplementation? >> >> Not requiring the users of freestanding implementations to roll their >> own implementations of that extra stuff. > > That's what you expect when you decide to use a freestanding > implmentation. If I want to use an the off-the shelf memcpy() > function, why not just link with libc?
Which libc? A freestanding implementation's libc might not have memcpy(). A third-party libc might not be available for my target device.
Reply by Philipp Klaus Krause May 8, 20202020-05-08
Am 08.05.20 um 17:56 schrieb Grant Edwards:
> > What's the benefit of requiring extra stuff for a freestanding > iplementation?
Not requiring the users of freestanding implementations to roll their own implementations of that extra stuff.