I know my C up to this point. I was looking at the source files of PHP I downloaded, and I saw this strange syntax:
PHPAPI int php_printf(const char *format, ...)
{
// code...
}
What does the PHPAPI do before the return type int? I've tried searching all over and I can't understand what this means. Is it a second return type? It can't be because the function does return an int. Maybe it extends to some other struct declared in a header file?
The hard way:
Go to the makefile and add in the line that compiles the sources: -E, by doing so you will see the source cose after the preprocessing phase.
The easy way:
Search all the project for PHPAPI:
find it in php.h:
#ifdef PHP_WIN32
#include "win95nt.h"
# ifdef PHP_EXPORTS
# define PHPAPI __declspec(dllexport)
# else
# define PHPAPI __declspec(dllimport)
# endif
#define PHP_DIR_SEPARATOR '\\'
#else
#define PHPAPI
#define THREAD_LS
#define PHP_DIR_SEPARATOR '/'
#endif
Now what you need to know is what is __declspec(dllexport) and what is __declspec(dllimport)
In the SO thread- What is __declspec and when do I need to use it?
see Alexander Gessler answer:
The canonical examples are __declspec(dllimport) and
__declspec(dllexport), which instruct the linker to import and
export (respectively) a symbol from or to a DLL.
// header
__declspec(dllimport) void foo();
// code - this calls foo() somewhere in a DLL
foo();
(__declspec(..) just wraps up Microsoft's specific stuff - to
achieve compatibility, one would usually wrap it away with macros)
Related
All across our C code base, I see every macro defined the following way:
#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#endif
#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#endif
#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#endif
#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
#endif
What is the rationale of doing these define checks instead of just defining the macros?
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
I can't find this practice explained anywhere on the web.
This allows you to override the macros when you're compiling:
gcc -DMACRONAME=value
The definitions in the header file are used as defaults.
As I said in the comment, imagine this situation:
foo.h
#define FOO 4
defs.h
#ifndef FOO
#define FOO 6
#endif
#ifndef BAR
#define BAR 4
#endif
bar.c
#include "foo.h"
#include "defs.h"
#include <stdio.h>
int main(void)
{
printf("%d%d", FOO, BAR);
return 0;
}
Will print 44.
However, if the conditional ifndef was not there, the result would be compilation warnings of MACRO redefinition and it will print 64.
$ gcc -o bar bar.c
In file included from bar.c:2:0:
defs.h:1:0: warning: "FOO" redefined [enabled by default]
#define FOO 6
^
In file included from bar.c:1:0:
foo.h:1:0: note: this is the location of the previous definition
#define FOO 4
^
I do not know the context but this can be used to give the user the availability to override the values set by those macro definitions. If the user explicitly defines a different value for any of those macros it will be used instead of the values used here.
For instance in g++ you can use the -D flag during compilation to pass a value to a macro.
This is done so that the user of the header file can override the definitions from his/her code or from compiler's -D flag.
Any C project resides on multiple source files. When working on a single source file the checks seem to (and actually) have no point, but when working on a large C project, it's a good practice to check for existing defines before defining a constant. The idea is simple: you need the constant in that specific source file, but it may have been already defined in another.
You could think about a framework/library that gives to the user a default preset that allow the user to compile and work on it.
Those defines are spreaded in different files and the final user is advised to include it's config.h file where he can config its values.
If the user forgot some define the system can continue to work because of the preset.
Using
#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#endif
allows the user to define the value of the macro using the command line argument (in gcc/clang/VS) -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f.
There is another important reason. It is an error to re-define a preprocessor macro differently. See this answer to another SO question. Without the #ifndef check, the compiler should produce an error if -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f is used as a command line argument in the compiler invocation.
On Apple's opensource website, the entry for stdarg.h contains the following:
#ifndef _STDARG_H
#ifndef _ANSI_STDARG_H_
#ifndef __need___va_list
#define _STDARG_H
#define _ANSI_STDARG_H_
#endif /* not __need___va_list */
#undef __need___va_list
What do the #define statements do if there's nothing following their first argument?
There are sort of three possible "values" for an identifier in the preprocessor:
Undefined: we don't know about this name.
Defined, but empty: we know about this name, but it has no value.
Defined, with value: we know about this name, and it has a value.
The second, defined but empty, is often used for conditional compilation, where the test is simply for the definedness, but not the value, of an identifier:
#ifdef __cplusplus
// here we know we are C++, and we do not care about which version
#endif
#if __cplusplus >= 199711L
// here we know we have a specific version or later
#endif
#ifndef __cplusplus // or #if !defined(__cplusplus)
// here we know we are not C++
#endif
That's an example with a name that if it is defined will have a value. But there are others, like NDEBUG, which are usually defined with no value at all (-DNDEBUG on the compiler command line, usually).
They define a macro which expands to nothing. It's not very useful if you intended it to be used as a macro, but it's very useful when combined with #ifdef and friends—you can, for example, use it to create an include guard, so when you #include a file multiple times, the guarded contents are included only once.
You define something like:
#define _ANSI_STDARG_H_
so that, later you can check for:
#ifdef _ANSI_STDARG_H_
i'm really noob in C. I just need to compile a ANSI C source to get a dll.
During compilation i get this error:
C2491: 'SelectML': definition of dllimport function not allowed
Where SelectML is a public function with this definition:
int CALLINGCONV SelectML(WORD fid, int nSlot)
{
WORD SW;
int x;
BYTE pSend[2];
pSend[0]=(BYTE)((fid&0xff00)>>8);
pSend[1]=(BYTE)(fid&0x00ff);
x=SendAPDUML(hCards[nSlot],APDU_SELECT,2,0,pSend,0,&SW);
if (x!=C_OK) return x;
if (SW!=0x9000) return SW;
return C_OK;
}
I'm sure the C source is good, maybe it is just a Visual Studio configuration...
This is another linked header:
#ifndef LIBSIAECARDT_H
#define LIBSIAECARDT_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(USE_STDCALL)
#define USE_STDCALL 1
#endif
#ifdef _WIN32
# if USE_STDCALL == 1
# define CALLINGCONV_1 _stdcall
# else
# define CALLINGCONV_1
# endif
# if defined(LIBSIAE_EXPORTS)
# define LIBSIAEAPI __declspec(dllexport)
# else
# define LIBSIAEAPI __declspec(dllimport)
# endif
# define CALLINGCONV LIBSIAEAPI CALLINGCONV_1
#else // ! _WIN32
# define CALLINGCONV
# define LIBSIAEAPI
# define CALLINGCONV_1
typedef unsigned int UINT;
#endif // _WIN32
It's common to have a macro like CALLINGCONV conditionally defined as __declspec(dllimport) or __declspec(dllexport) so that the same header file can be used in the library source and in the code using the library. Your build should probably define something that makes it use dllexport. Check how CALLINGCONV is defined or (preferably) consult any build documentation that came with the code.
Quoted in MSDN says it all. Do not define the function. Declaration is good. What you are doing here is defining SelectML which for sure is generating your C2491 Error.
Here's an alternative. Stop using MSVC. They explicitly dropped support for anything after C90. Use an actual C compiler for C code.
I've making a shared library (cross-platform), but when trying to compile the Windows build I'm encountering the error:
secure_string.h(43) : error C2059: syntax error : 'type'
This is in regards to the SECURESTRING_API macro. It doesn't complain about the two usages in strlcpy and strlcat, but when trying to use it for 'str_from_last' it generates the above error.
If I remove it, it compiles fine, but the function then isn't exported from the DLL, making it quite useless!
A Google search has yielded no (relevant) results; has anyone encountered this before? I've tested on both Visual Studio 2008 and 2010, and the result is identical. The source file includes string.h and then this file - nothing else.
Header file:
#ifndef SECURE_STRING_H
#define SECURE_STRING_H
/* Provide MS Builds with import/export functionality
* BUILD_SECURE_STRING should be added to project preprocessor macros */
#if _WIN32
# if defined(BUILD_SECURE_STRING)
# define SECURESTRING_API __declspec(dllexport)
# else
# define SECURESTRING_API __declspec(dllimport)
# endif
#else
# define SECURESTRING_API
#endif
/* Windows on the whole, and glibc do not have/support strlc[at|py]
* This will almost certainly need revision for proper cross-platform checks */
#if _WIN32 || __GLIBC__ || !defined(HAVE_STRLCPY)
size_t SECURESTRING_API strlcat(char* dst, const char* src, size_t size);
size_t SECURESTRING_API strlcpy(char* dst, const char* src, size_t size);
#else
# define HAVE_STRLCPY 1
#endif
/* In case the active project has yet to include headers for 'BOOL' */
#ifndef BOOL
# define BOOL int
# define TRUE 1
# define FALSE 0
#endif
/*
| Locates 'search' within 'source', and if found, returns either the
| character itself, or the character after it if 'return_from_after_found'
| is TRUE.
| If it is not found, or any parameter is invalid, a NULL pointer is returned.
*/
char* SECURESTRING_API
str_from_last(char* source,
char search,
BOOL return_from_after_found);
#endif /* SECURE_STRING_H */
#if _WIN32
Are you sure you're entering this? I would:
#if defined(WIN32)
EDIT: That looks OK but this I think is it:
move the SECURESTRING_API before the return type (char*):
SECURESTRING_API char*
With this change your code compiles for me under VS2010 and MSDN confirms that is the required order:
The decl-specifier-seq should contain, among other things, a base type
(e.g. int, float, a typedef, or a class name), a storage class (e.g.
static, extern), or the __declspec extension. The init-declarator-list
should contain, among other things, the pointer part of
declarations.
// common.h
// This is foo function. It has a body.
__inline void foo() { /* something */ }
// a.cpp
#include "common.h" // for foo function
// Call foo
// b.cpp
#include "common.h" // for foo function
// Call foo
I would like to inline the foo function only when I build for release. I don't want to inline functions for Debug build.
I tried it but linker errors annoyed me.
In this case, foo function's body is defined in common.h header file.
so if I just do
//common.h
#if !defined(_DEBUG)
__inline
#endif
void foo() { /* something */ }
It will be met a link error in DEBUG build. Because two modules try to include common.h.
I have no idea to solve it.
Is it possible?
The "easy" solution would be this:
#if !defined(_DEBUG) || defined(NDEBUG)
#define INLINE inline
#else
#define INLINE static
#endif
static is necessary to silence linking errors and get around the One Definition Rule.
A better solution would be to simply disable inlining project wide for debugging. GCC supports the -wno-inline-functions and -fno-inline-small-functions options to counteract those optimizations, and it also does not enable inlining for -O1 or lower (and probably -Os as well). Most compilers have similar options.
I call the latter a better solution because it should instruct the compiler to ignore the inline hint, eliminating the need for pesky preprocessor directives.
The fundamental thing to realize is that the inline keyword (or Microsoft's __inline extension for C - since MSVC doesn't support C99) is essentially a pass to violate the one definition rule. If you think about it - that's all it really is, since the compiler is under no obligation to actually perform any inlining.
So, when you have an inline function you're allowed to have the function defined in more than one module. In fact, you're obligated to have it defined in any module that actually uses the function.
However, if you don't declare the function as inline, you have to ensure that you have no more than one definition (exactly one if it actually gets used). For non-member functions (all function in C), there are a few ways around this:
declare the function as static to change it's linkage to internal (note that you can have static inline functions to begin with).
in C++ you can place them in an anonymous namespace (which has an effect similar to declaring the static)
you can use preprocessor manipulation to handle this. It's kind of ugly, but it works, and I've seen the technique used successfully in the wild. Whether it's worth the effort is another thing altogether - you'll have to decide that yourself.
Basically, what you need to do is have an implementation of the function in a separate .c file, just like if you were following the tradition of a-single-function-per-module coding standard (actually you can do this just as well putting several inline functions in the .c module - but they should all be inline or not inline as a group to keep things from getting too out of hand). The implementation of the function needs to arrange to be able to be included in a header - so it needs include guards, just like any other header. Then you use the preprocessor to conditionally include the implementation as part of the header when you want inline functions (so the implementation will be available to all modules), but don't include it if you're not inlining (so you follow the one definition rule in that case):
The common.h header:
// common.h
#ifndef COMMON_H
#define COMMON_H
#ifdef RELEASE
#define USE_INLINE
#define INLINE __inline
#else
#define INLINE
#endif
INLINE void foo(void);
#ifdef USE_INLINE
#include "foo.c"
#endif
#endif /* COMMON_H */
The implementation of foo():
// foo.c
#ifndef FOO_C
#define FOO_C
#include <stdio.h>
#include "common.h"
INLINE void foo()
{
printf("foo\n");
}
#endif /* FOO_C */
And an example program:
// main.c
#include<stdio.h>
#include "common.h"
int main()
{
foo();
return 0;
}
Now if you compile for release:
cl /DRELEASE main.c foo.c
foo() will be inline (or __inline as the case may be).
If you compile for non-release:
cl test.c foo.c
you have a non-inline foo().
And both the compiler and linker are happy in either case.
All that said, I kind of like the suggestion to maybe redefine INLINE to be static for debugging purposes.
However, ultimately I'm not sure I see the point to any of this really - modern debuggers are able to step through functions that are inline, and the debugger probably won't inline function calls if you disable optimizations. So you can set breakpoints inside the inline function as well and have it work fine in non-optimized builds.
I'm not sure exactly what you're end-goal in this really is. What's the drawback to leaving the functions as inline in debug/non-optimized builds?
#ifdef RELEASE
#define INLINE __inline
#else
#define INLINE
#endif
Then
// common.h
INLINE void foo() { /* something */ }
// a.cpp
#include "common.h" // for foo function
// Call foo
// b.cpp
#include "common.h" // for foo function
// Call foo
then define RELEASE for the release version. of course you can see from this there are lots of ways to do it.
You can't declare header only functions as non-inline. You could declare them as static (a.k.a. C-style static), but that will generate a copy of the function (including local static variables, if any) in each translation unit. A better solution is to leave it as inline. In debug mode when optimizations are disabled compilers usually don't inline any functions.
In most cases release flags are not defined. Typically debug flags are defined.
_DEBUG is defined by most compilers, so there is no need to define a release flag:
More practical:
#ifndef _DEBUG
__inline void foo() { /* something */ }
#else
//some alternative
#endif
Use compiler conditionals and define a compile time flag.
Example:
#ifdef RELEASE_BUILD_FLAG
//Run inline function
#else
//some alternative
#endif