In C programming, I have a set of information, and I have to ways of providing it to user:

  1. construct a data structure and provide it as an object.
  2. write a function to read them out and return them.

I used 2 for part of my project - some of my users expect to have those values available at compile-time, so function-like macros are needed, and the user code can work with both function-like macros and actual functions.

Here's my project, it's a cryptography library. And here's some background information.

Method 2 is used for obtaining working context size, key/block/output size for hash functions, AEAD ciphers, etc. and it work well for most symmetric-key algorithms. 2 is also used for asymmetric-key algorithms including key encapsulation mechnism and digital signature schemes.

Where compile-time and link/run-time deviates is when they're instantiated.

When an algorithm is instantiated at compile-time, a function-like macro is defined taking its parent algorithm, and specifying a parameter - take HMAC for example, HMAC is the parent algorithm, and a hash algorithm is the parameter.

When an algorithm is instantiated at link/run-time, a pointer to an object of type CryptoParam_t is specified as parameter.

But now, some of the information is known to be only available at run-time (or at least link-time) - asymmetric-key algorithm key-generation functions can only take CryptoParam_t objects is among the reasons. So is it better to just use 1? Is it an anti-pattern to use 2 now?

  • It depends on the information. The repository is large, the question needs more scope. What kind of information are we talking about? Keep in mind that option 2 also sorts of includes option 1, you can use a unit test to ensure your runtime function can read static data from a known source.
    – Ccm
    Aug 5, 2023 at 11:56
  • @Ccm I've edited the question. One thing came into my mind is that, when using data objects, no "text-segment" code is needed, which can save some space if my project is actually used in some "free-standing" embedded hardwares.
    – DannyNiu
    Aug 5, 2023 at 12:11

1 Answer 1


Ignoring for a moment that the library is free-standing. Obtaining public data through function is definitely NOT an anti-pattern.

For example, the public data is mutable, and the application is multi-threaded, functions can provide thread-safe ways to read, modify, and wait for change against the said data.

For the specific project mentioned in the OP, in addition to providing CryptoParam_t as public information objects, think what functions can add to it - instead of user duplicating codes that iterate over the algorithm instances table, a function can centralize that code, and provide easy way to

  • query for algorithm instances that provides a specific security level,
  • uses a specific family of underlaying algorithm (e.g. SHA-2 vs SHA-3/Keccak),
  • fed the hash algorithm instance, returning a suggested PRNG instance for use in e.g. RFC-6979-style deterministic signing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.