1

In C, how can I detect if a some form of malloc has been made available, regardless of target platform or compiler? Is it enough to detect _STDLIB_H_?

I would like to include a header utility function that uses malloc but only if it's already made available by library user.

UPDATE: The library requires some heap or stack memory allocation, the amount of which may or may not be known at compile time. The library can calculate, at runtime, the exactly amount of memory needed. So for those who need to wait till runtime and can/want to use heap memory, I want to make automatic allocation available. But I do not want the library itself to load 'stdlib.h'.

codechimp
  • 1,509
  • 1
  • 14
  • 21
  • See [C11 p4](http://port70.net/~nsz/c/c11/n1570.html#4) --> ie, if you're on a *hosted implementation*, you have the `malloc()` functionality "for free" (may not be available in *freestanding implementations*). – pmg Jan 18 '22 at 17:39
  • 2
    I don't get it. You have some nefarious plans for `malloc`, but only if the user has implicitly provided access to its prototype *prior* to including your header? Forgive me, but that is (a) incredibly brittle, and (b) trivially circumventable. Perhaps I misunderstood the question. – WhozCraig Jan 18 '22 at 17:40
  • @WhozCraig I want my library to be usable for embedded, or similarly small, platforms where memory frag is deadly and malloc is strong discouraged. But make library complete for larger OS-based platforms, where memory frag is not an issue. – codechimp Jan 18 '22 at 17:47
  • Maybe create pairs of functions? `mylib_foo_malloc(...)` and `mylib_foo_nomalloc(...)` etc... and use preprocessor magic to make use of those functions transparent? – pmg Jan 18 '22 at 17:49
  • 1
    Although a standard/conforming implementation will have `malloc` it might not have _other_ functions. (e.g.) Most but not all impl have `strdup`. Look at what `autoconf` does. It creates tiny test programs to probe for functions (or `.h` files or libraries, etc). It compiles them. If they compile and link cleanly, then the [given] function is provided. If it found that `strdup` was available, it would output (e.g.) `#define HAVE_STRDUP 1` to a "features" file (e.g. `features.h`). Include that. There are other such defines (e.g. `HAVE_STDIO_H` or `HAVE_LIBC_SO`) – Craig Estey Jan 18 '22 at 17:49
  • According to http://port70.net/~nsz/c/c11/n1570.html#4p6 a conforming *freestanding* implementation is not required to support `stdlib.h` functions. – Eugene Sh. Jan 18 '22 at 18:00
  • 1
    **C18 4.6** The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (Clause 7) is confined to the contents of the standard headers , , , , , , , , and . – Weather Vane Jan 18 '22 at 19:00
  • really dumb question, cant you just have a flag that the caller supplies at some point – pm100 Jan 18 '22 at 22:22
  • @WeatherVane I think you answered my question. Another words, yes, even in freestanding build environment, it is sufficient to test for `_STDLIB_H`. Not sure why you made this a comment rather than an answer. – codechimp Jan 19 '22 at 18:51
  • @codechimp: testing `_STDLIB_H` tells you nothing. Some implementation might use that symbol for something, but other implementations might not, and it might not have anything to do with malloc or stdlib.h – Chris Dodd Jan 19 '22 at 19:26
  • 1
    @codechimp in MS VC it is also declared in `malloc.h` but the C standard doesn't mention `malloc.h`. I don't know what is sufficient to test for function `malloc()` or `stdlib.h` hence no answer. With MS VC your `_STDLIB_H` isn't known whether or not I `#include ` It has a header guard but that is only set if the header is included, not whether available. The comment was to show that a conforming implementation does not need to provide `malloc()`. – Weather Vane Jan 19 '22 at 20:24
  • @codechimp __STDLIB_H__ is just an include guard, when including stdlib.h. It does not say, it's really available or not. Someone could also just remove or not declare the Heap in the linker command file. – kesselhaus Jan 20 '22 at 07:32

1 Answers1

2

It sounds like what you want to do is produce a single library binary that can be used in both freestanding (embedded) and hosted (non-embedded) environments. This is tricky but possible.

If you are building a static library (which it probably needs to be anyways -- generally shared libraries will not be useful in an embedded environment), you can just use malloc in part of your library and, as long as that part is not used by the application, it will not be included and all will be fine. If an embedded application uses the thing that requires malloc, they'll then get a link-time error if the embedded environment does not provide it.

So what you end up needing to do is offer two entry points for your library -- one that requires malloc and one that does not -- and the user (application writer) needs to call the one that is appropriate for their environment. You need to make sure that these two entry points are included in the library such that only one needs to be linked (generally, just make sure they are in different compilation units).

But I do not want the library itself to load 'stdlib.h'

This statement indicates a fundamental misunderstanding about what is going on. stdlib.h is a header file, not a library, so you do not (and cannot) "load" it. You can include it in your source code, but that just gives you the declarations for what is in the library; it does not include any of the library in your library. If you don't use anything from the header, it will have no effect. If you do use things from the header, that will create dependencies in your library on the standard library that will need to be resolved at (application) link time.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • The point of my question is whether it is garunteed that a `malloc` deceleration is ALWAYS confined to `stdlib.h`, even in embedded build system. But @Weather Vane, seemed to answer that question in the form of a comment regarding C18 4.6. – codechimp Jan 19 '22 at 18:54
  • Why do you care if `malloc` is declared (only) in stdlib.h or not? – Chris Dodd Jan 19 '22 at 19:30
  • @codechimp The compiler can still have the headers there. BUT, it is the developers choice to use them or not. And if they use them, they should also make sure, the heap is actually configured in the linker command file. Because the embedded compiler can be used for both a hosted and freestanding environment still. – kesselhaus Jan 20 '22 at 07:37
  • @ChrisDodd Because I assume in non-conforming build sys, the library are non-standard (i.e. the 'std' in 'stdlib.h'). I want it to use which ever `malloc` the end-user chooses to implement/use, based on their particular target platform, and not throw error or warning simply for being there if their target does not support/declare `malloc`. Equally important, I want to throw error if `malloc` is NOT supported and they attempt to use the add-on function. – codechimp Jan 20 '22 at 17:24
  • For such a use, you'll need to provide the end user a way to specify the allocation function to use -- you could have them provide a pointer to an allocation function (which could be malloc if that is what they want to use, or might have a different name) and possibly a deallocation function as well – Chris Dodd Jan 20 '22 at 19:22
  • Alternately, just `#include ` and call `malloc`. If they use the function that requires malloc and they don't have it, they'll get a link time error. If they don't use that function (or anything else in the same compilation unit, possibly) then things will link and run fine. – Chris Dodd Jan 20 '22 at 20:00