C: Difference between revisions
Jump to navigation
Jump to search
(→Variadic I/O Functions: don't forget to call va_end()) |
|||
Line 121: | Line 121: | ||
== Debugging == |
== Debugging == |
||
See general page on [[Debugging]]. |
See general page on [[Debugging]]. |
||
== Embedded C == |
|||
Some tips to make embedded development with C. |
|||
=== Enums are not always int === |
|||
Some compilers do not necessarily map ''enum'' types to ''int''. The ARM compiler for instance will by default use the smallest date type that can hold the value of all enumerators. |
|||
<source lang=c> |
|||
typedef enum MyEnum_t { |
|||
first = 1, |
|||
second = 2, |
|||
_forceint = 0x7FFFFFFF // To force 32-bit (signed) enum |
|||
} MyEnum_t; |
|||
</source> |
|||
== Win32 vs Linux == |
== Win32 vs Linux == |
Revision as of 08:49, 8 August 2012
References
- The C Library Reference Guide
- C Preprocessor reference
- manpage manpages-dev
- manpage manpages-posix-dev
sudo apt-get install manpages-dev manpages-posix-dev
Tips
Struct Initializer
struct {
int a;
int b;
} s = { .a = 1, .b = 2 };
Same applies for union.
Variadic Macros
See reference here.
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
/* eprintf ("%s:%d: ", input_file, lineno)
==> fprintf (stderr, "%s:%d: ", input_file, lineno) */
#define eprintf(args...) fprintf (stderr, args)
#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)
An handy macro hack that counts the number of parameters passed before expansion (See [1] and [2]):
/* The PP_NARG macro returns the number of arguments that have been
* passed to it. This compensates for lack of __VA_NARGS__.
* Macros written by Laurent Deniau See http://en.wikipedia.org/wiki/Variadic_macro.
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
/* Some test cases */
PP_NARG(A) -> 1
PP_NARG(A,B) -> 2
PP_NARG(A,B,C) -> 3
PP_NARG(A,B,C,D) -> 4
PP_NARG(A,B,C,D,E) -> 5
PP_NARG(1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3) -> 63
Variadic I/O Functions
See [3] for some reference information on variable functions.
The standard variadic I/O functions are:
#include <stdio.h>
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
Example of use:
//This works both on win32 / linux
#include <stdio.h>
#include <stdarg.h>
void vario(const char* formatstr,...)
{
va_list args;
va_start(args, formatstr);
vprintf(formatstr, args);
va_end(args); /* cleanup - DON'T FORGET */
}
Note on win32:
- There exists alternative functions ([4]) prefixed with a '_', such as
_vprintf_p
,_vfprintf_l
, ...
Temporary variable names for Macro
/* UNIQ(x) creates a unique variable name that depends on the current source line as returned by __LINE__. We need
Several intermediate macros because identifier are not expanded in macro if they are used along with # or ## in
macro definition.
Example: #define SCAN_MY(var,n) {int UNIQ(x); for(UNIQ(x)=0; UNIQ(x)<n; ++UNIQ(x)) printf(var[UNIQ(x)]);}
*/
#define UNIQ__(x,y) x ## y
#define UNIQ_(x,y) UNIQ__(x,y)
#define UNIQ(x) UNIQ_(x,__LINE__)
Debugging
See general page on Debugging.
Embedded C
Some tips to make embedded development with C.
Enums are not always int
Some compilers do not necessarily map enum types to int. The ARM compiler for instance will by default use the smallest date type that can hold the value of all enumerators.
typedef enum MyEnum_t {
first = 1,
second = 2,
_forceint = 0x7FFFFFFF // To force 32-bit (signed) enum
} MyEnum_t;
Win32 vs Linux
Linux | Win32 | Comment |
---|---|---|
snprintf |
_snprintf |
deprecated, replaced by _snprintf_s but not compatible
|