0

I have the following weakly linked declaration:

extern __attribute__((visibility ("default"))) Type* const symbolName __attribute__((weak_import));

The problem is, the symbol may or may not be defined, depending on the operating system.

So, when I use it func(symbolName);, I get a signal 11 crash because I am attempting a dereference of null. I could ask if(&symbolName != NULL) { func(symbolName); }, but that would require everyone using this symbol to remember asking this question, which is not optimal.

I am looking for some wizardly magic to conditionally modify or redeclare this symbol, only if unavailable, to have some default value which my func would work with.

I understand this is an ugly solution and is not recommended. At this point, I just want to know if there is a way to do it, no matter how ugly or low-level.

bneely
  • 9,083
  • 4
  • 38
  • 46
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • There is platform specific stuff here. If that is relevant, please tag appropriately. – John Dibling Jul 31 '13 at 12:28
  • My first question would be how does client code even compile & link clean if the symbol is not defined? – John Dibling Jul 31 '13 at 12:29
  • Why not just do the `NULL` check *in* the function? Before you actually dereference it? And if you can't change all the functions the pointer is used in (for example they are part of the standard library) then checking for `NULL` before calling is the standard way. – Some programmer dude Jul 31 '13 at 12:29
  • @JohnDibling Thanks, it's on ARM/iOS. Code compiles because the symbol is defined as `extern`. – Léo Natan Jul 31 '13 at 12:34
  • @JoachimPileborg The symbol is dereferenced first, then the function is called with the dereferenced value. Dereferencing the undefined symbol causes a signal 11. – Léo Natan Jul 31 '13 at 12:36
  • @JoachimPileborg: The impression I'm getting is that the function might not exist. – John Dibling Jul 31 '13 at 12:41
  • @LeoNatan: OK, that describes why the code compiles, but how does it link? – John Dibling Jul 31 '13 at 12:42
  • The function exists. I define and implement it in my project. The problem is, it is called with a symbol that may or may not exist. – Léo Natan Jul 31 '13 at 12:43
  • @LeoNatan The variable is a pointer, if it's defined (but not initialized) you can pass it around all you want. In your example you don't actually dereference it when calling the function, as you don't use the dereference operator `*` as in `func(*symbolName)`. Also, your `NULL` check is wrong, as you use the address-of operator `&` leading you to check if the address to the pointer is `NULL` (which it will never be). – Some programmer dude Jul 31 '13 at 12:45
  • @JohnDibling It links because there is an availability attribute which allows it to succeed. As per: http://clang.llvm.org/docs/LanguageExtensions.html#availability-attribute – Léo Natan Jul 31 '13 at 12:46
  • Can you please show more of a context? Is it the actual *definition* of the variable that is conditional, or the *initialization* of the variable? Please edit your question to include a [SSCCE](http://sscce.org/). – Some programmer dude Jul 31 '13 at 12:46
  • @JoachimPileborg I think you misunderstand. The variable is a symbol which points to a location in memory which points to the value of the variable. The problem is, the symbol itself is equal to NULL. Calling `symbolName` dereferences the symbol pointer, which is NULL. – Léo Natan Jul 31 '13 at 12:48
  • @LeoNatan: Aha, I see now. Since this might confuse others, I'll edit your post a bit. – John Dibling Jul 31 '13 at 12:50
  • So the variable is always there, it's just initialized to `NULL` sometimes? Then you need to check for that *somewhere*. If the check is in the function you call, or before the function doesn't really matter (though I would recommend the former). – Some programmer dude Jul 31 '13 at 12:50
  • @JoachimPileborg You don't understand what I want in this question. Please stop cluttering the comments. Please reread the question and if you cannot contribute, allow others to. – Léo Natan Jul 31 '13 at 12:55
  • Could you conditionally link a default definition based on the OS? – Jiminion Jul 31 '13 at 14:02
  • @Jim Could you please give an example? I am trying to do that now, currently trying adding a new framework in Xcode which will conditionally define it for OS version lower than the one that defines it. – Léo Natan Jul 31 '13 at 14:26
  • Could you write a tiny c file that has the benign definition in it? Then you could conditionally compile and link that based on the OS. That would be easier than building a definition on the fly in a build script (at least for me.....) – Jiminion Jul 31 '13 at 14:30
  • @Jim The problem is not just OS type, but OS version, and that is determined at runtime. – Léo Natan Jul 31 '13 at 14:35
  • **Option1** Try multiple declarations of same symbol name with ` __attribute__((availability(` having different range different `introduced` and `obsoleted` version numbers. **Option2** Do NOT export this symbol-name for use elsewhere. Write your wrapper around it which does the null check and calls the function only if it exists or otherwise asserts warnings(or pretty much anything you want) during run-time. Export this wrapper function for use everywhere. – TheCodeArtist Jul 31 '13 at 16:03
  • @TheCodeArtist Thanks. I tried Option1 and was unable to achieve what I wanted. Either it would override it in both operating systems or it wouldn't work and it would not be defined in one OS. Option 2 is always possible, of course, but then every developer would have to remember to use our own implementation instead of framework standard (where he might read on the internet). – Léo Natan Jul 31 '13 at 18:39

0 Answers0