Does Windows have a __declspec equivalent to Unix GCC's __attribute__((weak))? - c

I want to import some C code but override its main() function. I can do this in Unix by prefacing the C code's main declaration with __attribute__((weak)), however, this won't compile in Windows, because neither Strawberry Perl's GCC nor MinGW's GCC recognize __attribute__((weak)).
Reading the docs online, __declspec seems to function similarly. Is there a __declspec equivalent to Unix GCC's __attribute__((weak)) macro?
This is a more specific version of an earlier question I posted.

There's another way with MSVC that I think would work if you care to use it.
/*
* pWeakValue MUST be an extern const variable, which will be aliased to
* pDefaultWeakValue if no real user definition is present, thanks to the
* alternatename directive.
*/
extern const char * pWeakValue;
extern const char * pDefaultWeakValue = NULL;
#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")
See this old SO answer for some other options.

There's also __declspec(selectany)

Related

Function pointer usage with hierarchical control: xtern/namespace C++

Below is a sample usage from an older and newer version of a software stack. How would the function usage and access differ with the hierarchical structuring of the two pieces of
code below:
namespace std
{
typedef void (*function)();
extern "C" function fn_ptr(function) throw();
}
And
extern "C++"
{
namespace std
{
typedef void (*function)();
function fn_ptr(function) throw();
}
}
The first one is easy but I wish to access fn_ptr from both C and
C++ based files in the 2nd example. Note that it is extern "C++" and there isn't much to find about extern "C++" usage on Stackoverflow or Google.
The second version does not allow direct access from a program written in C.
Of course, nothing stops the C program from calling some other C++ function declared extern "C", which in turn calls std::fn_ptr.
Although this point has been hammered into the ground in comments, it's worth noting that you are not allowed to define your own names in namespace std. Presumably the code you are quoting comes from a library implementation designed to be used in a stand-alone environment. Using namespace std is not relevant to the issue, and is just a distraction from your question.
Here is the unique approach to accessing a function defined in C++ from C. extern "C++" is implicit by default in standard.
Let us assume that you have a .c file (FileC.c) and you wish to call a function defined in .cpp (FileC++.cpp). Let us define the function in C++ file as:
void func_in_cpp(void)
{
// whatever you wanna do here doesn't matter what I am gonna say!
}
Do the following steps now (to be able to call the above function from
a .c file):
1) With you regular C++ compiler (or www.cpp.sh), write a very simple program that includes your function name (func_in_cpp). Compile your program. E.g.
$ g++ FileC++.cpp -o test.o
2) Find the mangled name of your function.
$ nm test.out | grep -i func_in_cpp
[ The result should be "_Z11func_in_cppv" ]
3) Go to your C program and do two things:
void _Z11func_in_cppv(void); // provide the external function definition at the top in your program. Function is extern by default in C.
int main(void)
{
_Z11func_in_cppv(); // call your function to access the function defined in .cpp file
}

What are these function and parameter annotations?

The source code for busybox's syslogd implementation contains some annotations I'm unfamiliar with. The language is C, not C++.
int syslogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int syslogd_main(int argc UNUSED_PARAM, char **argv)
Specifically, MAIN_EXTERNALLY_VISIBLE and UNUSED_PARAM.
What exactly are these annotations doing? Where can I read more about them and other annotations?
Are these part of the C standard, or are they compiler extensions? If they are compiler extensions, how widely supported are they?
I assume the first one is why this file doesn't have a main() function. If these are compiler extensions rather than part of the standard, does this mean this file can't be meaningfully compiled as-is by a compiler that adheres only to the C standard?
Why did they declare a prototype of the syslogd_main function immediately before the full definition? Can the MAIN_EXTERNALLY_VISIBLE annotation only be applied to function prototypes?
1. What exactly are these annotations doing?
See include/platform.h and include/libbb.h
UNUSED_PARAM expands to __attribute__ ((__unused__)). It specifies the variable (argc in your example) as "possibly unused" and disables the "unused variable" warning.
From the GCC manual [Specifying Attributes of Variables]:
unused
This attribute, attached to a variable, means that the variable is meant to be possibly unused. GCC will not produce a warning for this variable.
MAIN_EXTERNALLY_VISIBLE expands to EXTERNALLY_VISIBLE and then to __attribute__(( visibility("default") )). It controls the visibility of the function.
From the GCC manual [Declaring Attributes of Functions]:
... On ELF, default visibility means that the declaration is visible to other modules and, in shared libraries, means that the declared entity may be overridden.
From include/libbb.h:
/* We need to export XXX_main from libbusybox
* only if we build "individual" binaries
*/
#if ENABLE_FEATURE_INDIVIDUAL
#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
#else
#define MAIN_EXTERNALLY_VISIBLE
#endif
2. Are these part of the C standard, or ...?
No, those are macros defined in the BusyBox project.
3. I assume the first one is why this file doesn't have a main() function. ...
No. BusyBox combines many utilities into a single executable. That explains the "lack of a main() function" in syslogd.c.
4. Why did they declare a prototype of the syslogd_main function immediately before the full definition? ...
From the GCC manual [Declaring Attributes of Functions]:
The keyword __attribute__ allows you to specify special attributes when making a declaration.

Unusual C function declaration

I'm currently working with an old C library (made in the early 90's) and the following function declaration made me confused :
#define bland_dll
typedef unsigned short int usint;
typedef unsigned char uchar;
int bland_dll Read_Chan (usint channel);
What is the bland_dll doing between the function's name and it's return type ?
Thanks for your lights!
Its a macro defining empty, so when preprocessed it turns out to be:
int Read_Chan (usint channel);
I suspect, its a holdover from the early days when declaring DLL linkage types, like pascal which has a special meaning to the linker, for example. Another example is __cdecl.
For completion of the idiosyncracies of compiler linkage mechanisms:
__stdcall
__fastcall
__cdecl
Each of them influenced how the linker managed the name decoration at compile time, and may have caused conniptions with linking to third party DLL's due to the differing link time switches.
Edit: Thanks unwind for the correction.

How to check if the declaration is 'extern' in GCC GENERIC?

I'm playing with GCC IR and I want to check if the declaration was extern in C source:
extern int i;
I want to do that on GENERIC tree, to get something like this (by analogy to TREE_STATIC macro):
tree t;
if (TREE_EXTERN (t))
// do handling of extern
I've checked the GCC Internals documentation, but didn't find the needed function or macro.
I'm not an expert on GCC internals, but perhaps DECL_EXTERNAL is what you're looking for?

How can I tell gcc not to inline a function?

Say I have this small function in a source file
static void foo() {}
and I build an optimized version of my binary yet I don't want this function inlined (for optimization purposes). is there a macro I can add in a source code to prevent the inlining?
You want the gcc-specific noinline attribute.
This function attribute prevents a
function from being considered for
inlining. If the function does not
have side-effects, there are
optimizations other than inlining that
causes function calls to be optimized
away, although the function call is
live. To keep such calls from being
optimized away, put
asm ("");
Use it like this:
void __attribute__ ((noinline)) foo()
{
...
}
GCC has a switch called
-fno-inline-small-functions
So use that when invoking gcc. But the side effect is that all other small functions are also non-inlined.
I know the question is about GCC, but I thought it might be useful to
have some information about compilers other compilers as well.
GCC's
noinline
function attribute is pretty popular with other compilers as well. It
is supported by at least:
Clang (check with __has_attribute(noinline))
Intel C/C++ Compiler (their documentation is terrible, but I'm
certain it works on 16.0+)
Oracle Solaris Studio back to at least 12.2
ARM C/C++ Compiler back to at least 4.1
IBM XL C/C++ back to at least 10.1
TI 8.0+ (or 7.3+ with --gcc, which will define __TI_GNU_ATTRIBUTE_SUPPORT__)
Additionally, MSVC supports
__declspec(noinline)
back to Visual Studio 7.1. Intel probably supports it too (they try to
be compatible with both GCC and MSVC), but I haven't bothered to
verify that. The syntax is basically the same:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (and probably older) supports a noinline pragma which
applies to the next function:
#pragma noinline
static void foo(void) { }
TI 6.0+ supports a
FUNC_CANNOT_INLINE
pragma which (annoyingly) works differently in C and C++. In C++, it's similar to PGI's:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
In C, however, the function name is required:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (and possibly earlier) takes a similar approach, requiring
the function name:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio also supports a pragma which takes the
function name, going back to at least Forte Developer
6,
but note that it needs to come after the declaration, even in recent
versions:
static void foo(void);
#pragma no_inline(foo)
Depending on how dedicated you are, you could create a macro that
would work everywhere, but you would need to have the function name as
well as the declaration as arguments.
If, OTOH, you're okay with something that just works for most people,
you can get away with something which is a little more aesthetically
pleasing and doesn't require repeating yourself. That's the approach
I've taken for Hedley, where the
current version of
HEDLEY_NEVER_INLINE
looks like:
#if \
HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
# define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_NEVER_INLINE __declspec(noinline)
#elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
# define HEDLEY_NEVER_INLINE _Pragma("noinline")
#elif HEDLEY_TI_VERSION_CHECK(6,0,0)
# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
# define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif
If you don't want to use Hedley (it's a single public domain / CC0
header) you can convert the version checking macros without too much
effort, but more than I'm willing to put in ☺.
A portable way to do this is to call the function through a pointer:
void (*foo_ptr)() = foo;
foo_ptr();
Though this produces different instructions to branch, which may not be your goal. Which brings up a good point: what is your goal here?
In case you get a compiler error for __attribute__((noinline)), you can just try:
noinline int func(int arg)
{
....
}
static __attribute__ ((noinline)) void foo()
{
}
This is what worked for me.
Use the noinline attribute:
int func(int arg) __attribute__((noinline))
{
}
You should probably use it both when you declare the function for external use and when you write the function.
I work with gcc 7.2. I specifically needed a function to be non-inlined, because it had to be instantiated in a library. I tried the __attribute__((noinline)) answer, as well as the asm("") answer. Neither one solved the problem.
Finally, I figured that defining a static variable inside the function will force the compiler to allocate space for it in the static variable block, and to issue an initialization for it when the function is first called.
This is sort of a dirty trick, but it works.
I couldn't get __attribute__((noinline)) to work, but this works on clang and GCC.
The Linux kernel defines noinline.
include/linux/compiler_attributes.h:#define noinline __attribute__((__noinline__))
#include <linux/kernel.h>
static noinline void foo(void);

Resources