So today's exercise wants me to use this header.h obviously to give me the function corresponding to the operator.
#ifndef __HEADER__
#define __HEADER__
operator operator_table[] = {{"-", &function_sub}, \
{"+", &function_add}, \
{"*", &function_mul}, \
{"/", &function_div}, \
{"%", &function_mod}};
#endif
First thing I noticed is that operator type isn't defined so maybe I should typedef it to an int ?
Then the real problem start, I've read both K&R and C Primer Plus from beginning and haven't encountered this syntax, or at least I don't recognize it, is it some kind of dictionary ? How can I use it ?
It seems to be an array of structures, the structure (named operator) containing a string and a function pointer. There is no special syntax, just a normal array definition and initialization.
The \ is part of the preprocessor, and is a line-continuation "operator". It simply means that the preprocessor will create a single line out of this for the compiler to see.
operator here is a structure. and it could be defined in this way:
typedef struct {
char *op;
int (*func)(int, int);
} operator;
func here is a pointer to a function
function_sub, function_add, function_mul, function_div and function_mod should be a functions defined in your c code
In C, operator is not a keyword (which is not the case in C++ for example), and is here used as a symbol representing a type. So either it is typedef'd somewhere or it needs defining.
Looking at the array, this is an array of structs, the structure corresponding to operator being made of a char * and a function pointer. "+" is associated to function_add(type, type), and so on. type is not specified here as it cannot be inferred from this piece of code. The same applies to the number of arguments, I assumed 2 but this is arbitrary.
So, to use header.h, you have either to:
include in your .c file the header file that defines operator, if it exists.
or define it your own way without forgetting to define the functions in charge of the actual processing.
For example:
#ifndef __OPERATOR_HEADER__
#define __OPERATOR_HEADER__
float function_add(float, float);
float function_sub(float, float);
/* etc, the body of these function being defined in your .c file */
typedef struct operator {
char *operator_name;
float (*operator_function)(float, float);
};
#endif
Related
How might we write a preprocessor macro to replace every instance of:
func(
with
func((DemoUnion)?
Also, maybe a macro to replace func((DemoUnion)(DemoUnion) with func((DemoUnion)?
By the way, below is an example of how DemoUnion might be defined:
union DemoUnion {
char c;
short s;
int i;
float f;
}; typedef union DemoUnion DemoUnion;
// the typedef allows us to declare instances by writing
// DemoUnion instanceName;
// instead of:
// union DemoUnion instanceName;
Also, C allows us to cast to union types pretty easily:
(so long as the input to the cast is one of the types included in the union)
int main() {
DemoUnion big = 0;
char c = 1;
big = (DemoUnion) c; // cast char to union type
func(big);
func((DemoUnion) c);
}
How might we write a preprocessor macro to replace every instance of:
func(
with
func((DemoUnion)?
We wouldn't write such a macro, because C does not afford a way to do it. Macro expansion replaces the macro identifier and, for function-like macros, its argument list, with the macro's replacement text. The ( character cannot be part of a macro identifier, and it is not, by itself, an argument list. Thus, func( is not a unit that is subject to macro expansion.
You could, however, do this:
#define func(x) func((DemoUnion)(x))
That will have about the effect you describe, but it is specific to argument-list length. Also, you do not have to worry about recursive expansion; C specifies that it does not happen.
Also, maybe a macro to replace func((DemoUnion)(DemoUnion) with
func((DemoUnion)
Nope. Macro replacement replaces macros, not general text patterns. Anyway, anywhere that a (DemoUnion) cast is valid, (DemoUnion)(DemoUnion) is also valid and equivalent.
But note well that you have a serious misconception:
Also, C allows us to cast to union types pretty easily: (so long as
the input to the cast is one of the types included in the union)
On the contrary, C does not allow casting to or from union types. At all. Some compilers will accept such casts as an extension, but it is non-standard. The closest the (C2011) standard permits would involve using a compound literal:
DemoUnion u = (DemoUnion) { .c = c };
Note well that although part of the syntax for a compound literal resembles a cast operator, there is no cast there. But really, why do that, when you can just use an ordinary initializer:
DemoUnion u = { .c = c };
... or ordinary member assignment:
DemoUnion u;
u.c = c;
as the situation warrants.
Going the other way, of course, you should just use member selection:
char c2 = u.c;
It is not possible to have define name with "(". However, you may use function macro:
#define FOO(X) FOO((DemoUnion) (X))
or with variable number of arguments:
#define FOO(...) FOO((DemoUnion) __VA_ARGS__)
I wonder if typedef and #define are the same in c?
typedef obeys scoping rules just like variables, whereas define stays valid until the end of the compilation unit (or until a matching undef).
Also, some things can be done with typedef that cannot be done with define.
For example:
typedef int* int_p1;
int_p1 a, b, c; // a, b, c are all int pointers
#define int_p2 int*
int_p2 a, b, c; // only the first is a pointer, because int_p2
// is replaced with int*, producing: int* a, b, c
// which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp; // func_p is a pointer to a function that
// takes an int and returns an int
No.
#define is a preprocessor token: the compiler itself will never see it.
typedef is a compiler token: the preprocessor does not care about it.
You can use one or the other to achieve the same effect, but it's better to use the proper one for your needs
#define MY_TYPE int
typedef int My_Type;
When things get "hairy", using the proper tool makes it right
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
No, they are not the same. For example:
#define INTPTR int*
...
INTPTR a, b;
After preprocessing, that line expands to
int* a, b;
Hopefully you see the problem; only a will have the type int *; b will be declared a plain int (because the * is associated with the declarator, not the type specifier).
Contrast that with
typedef int *INTPTR;
...
INTPTR a, b;
In this case, both a and b will have type int *.
There are whole classes of typedefs that cannot be emulated with a preprocessor macro, such as pointers to functions or arrays:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Try doing that with a preprocessor macro.
#define defines macros.
typedef defines types.
Now saying that, here are a few differences:
With #define you can define constants that can be used in compile time. The constants can be used with #ifdef to check how the code is compiled, and specialize certain code according to compile parameters.
You can also use #define to declare miniature find-and-replace Macro functions.
typedef can be used to give aliases to types (which you could probably do with #define as well), but it's safer because of the find-and-replace nature of #define constants.
Besides that, you can use forward declaration with typedef which allows you to declare a type that will be used, but isn't yet linked to the file you're writing in.
Preprocessor macros ("#define's") are a lexical replacement tool a la "search and replace". They are entirely agnostic of the programming language and have no understanding what you're trying to do. You can think of them as a glorified copy/paste mechanic -- occasionally that's useful, but you should use it with care.
Typedefs are a C language feature that lets you create aliases for types. This is extremely useful to make complicated compound types (like structs and function pointers) readable and handlable (in C++ there are even situations where you must typedef a type).
For (3): You should always prefer language features over preprocessor macros when that's possible! So always use typedefs for types, and constant values for constants. That way, the compiler can actually interact with you meaningfully. Remember that the compiler is your friend, so you should tell it as much as possible. Preprocessor macros do the exact opposite by hiding your semantics from the compiler.
They are very different, although they are often used to implement custom data types (which is what I am assuming this question is all about).
As pmg mentioned, #define is handled by the pre-processor (like a cut-and-paste operation) before the compiler sees the code, and typedef is interpreted by the compiler.
One of the main differences (at least when it comes to defining data types) is that typedef allows for more specific type checking. For example,
#define defType int
typedef int tdType
defType x;
tdType y;
Here, the compiler sees variable x as an int, but variable y as a data type called 'tdType' that happens to be the same size as an int. If you wrote a function that took a parameter of type defType, the caller could pass a normal int and the compiler wouldn't know the difference. If the function instead took a parameter of type tdType, the compiler would ensure that a variable of the proper type was used during function calls.
Also, some debuggers have the ability to handle typedefs, which can be much more useful than having all custom types listed as their underlying primitive types (as it would be if #define was used instead).
No. typedef is a C keyword that creates an alias for a type. #define is a pre-processor instruction, that creates a text replacement event prior to compilation. When the compiler gets to the code, the original "#defined" word is no longer there. #define is mostly used for macros and global constants.
AFAIK, No.
typedef helps you set up an "alias" to an existing data type. For eg. typedef char chr;
#define is a preprocessor directive used to define macros or general pattern substitutions. For eg. #define MAX 100, substitutes all occurrences of MAX with 100
As mentioned above, there is a key difference between #define and typedef. The right way to think about that is to view a typedef as being a complete "encapsulated" type. It means that you cannot add to it after you have declared it.
You can extend a macro typename with other type specifiers, but not a typedef'd typename:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Also, a typedef'd name provides the type for every declator in a declaration.
#define fruit int *
fruit apple, banana;
After macro expansion, the second line becomes:
int *apple, banana;
Apple is a pointer to an int, while banana is an int. In comparison. a typedef like this:
typedef char *fruit;
fruit apple, banana;
declares both apple and banana to be the same. The name on the front is different, but they are both pointers to a char.
Another reason to use typedef (which has only been mentioned briefly in other answers and yet I think is the entire reason typedef was created) is to make debugging easier when using libraries that have custom types. For example, I'll use a type-conversion error. Both the codes below will print a compile-time error saying that a char is not comparable to a string, but in different ways.
typedef char letter;
letter el = 'e';
if(el == "hello");
The above code will print something like the variable "el" of type letter (aka "char") is not compatable with type "char*"
#define letter char
letter el = 'e';
if(el == "hello");
This code will instead print the variable "el" of type char is not compatable with type "char*"
This may seem silly because I'm defining "letter" as "char", but in more complex libraries this can be extremely confusing because pointers to objects like buttons, windows, sound servers, images, and lots of other things are defined as unsigned char *, which would only be debuggable as exactly that when using the #define method.
As everyone said above, they aren't the same. Most of the answers indicate typedef to be more advantageous than #define.
But let me put a plus point of #define :when your code is extremely big, scattered across many files, it's better to use #define; it helps in readability - you can simply preprocess all the code to see the actual type definition of a variable at the place of its declaration itself.
I have a *.H that define a struct. Like this:
#define nfloats 9999
#define nword 655
typedef struct {
int a
short b
unsigned short d
float e
char t[nword]
short un[14]
float dat[nfloats];
} datafile
In a void c all parameters of datafile is assigned a value. I want to pass the assigned values to main fortran program without having to redefine using TYPE. Just calling *.H and iso_c_binding. In other words, I wish use "datafile" in fortran main program that was already defined in *. H. Someone suggests something?
Thanks a lot!
The easiest way is to write a script in your favourite language that reads the C definition and converts it to Fortran. If you fix your syntax then it is quite easy.
1) #define xxx yyy becomes integer, parameter:: xxx = yyy
2) There is no unsigned in Fortran so unsigned shorts and shorts are both integer(kind=1).
3) It depends on how you are using the character arrays. If they are returning individual characters, not assigned en block, then they can be declared as character t(nword). If they are expected to hold strings then they should be declared character(len=nword) t.
4) typedef struct {
...
} datafile
becomes
type datafile
sequence
...
end type
5) Having done all that, you need to make sure that both the C and Fortran code have the same byte alignment. Your char array of 655 is not on a byte boundary so you might get alignment problems.
A second method is to play with macros and get the macros to do the generation for you. You need to define one set of macros for C and another set for Fortran. So you'd get something like
STRUCT_BEG(datafile)
INTEGER(a)
SHORT(b)
...
CHARA(t,nword)
FLOATA(dat,nfloats)
STRUCTEND(datafile)
The C defines would be
#define STRUCT_BEG(ignore) typedef struct {
#define STRUCT_END(name) } name;
#define INTEGER(a) int a;
#define CHARA(a,length) char a[length];
The Fortran defines would be something like
#define STRUCT_BEG(name) \
type name \
sequence
#define STRUCT_END(ignore) end type
#define INTEGER(a) integer::a
#define CHARA(a,length) character(len=length):: a
If you compile with -e, the C compiler can be used to generate both headers.
Please share with us your favorite, and most general, PRINT or DEBUG macro
applicable to all (or almost all) variables in different types and to arrays in C. The macro
can have any number of parameters (though 1-3 are preferred); if it increases
descriptive power at all, C99 features can be assumed.
#define PRINT(var, ...) \
...
Let's begin!
For C++, template function can be much more powerful than macro.
template <typename T>
std::string tostring(const T& t);
The drawback of template argument is that it cannot distinguish between typedef aliases:
typedef LONG HRESULT;
For C, I think there is nothing you can do, without changing your structs. If you have control over the struct definitions, here are two tricks:
Add a field to the beginning of the struct, and set the field to a value that uniquely identifies the type of the structure, which can be used by the tostring function to choose the appropriate printing code.
typedef struct abcde
{
int unique_struct_type_id; // assign this to a number that represents "abcde"
};
A similar method is to pass in a function pointer for printing the struct.
struct abcde
{
void (*print_fn) (abcde* p); // assign this to the printing function for "abcde"
}
#define PRINT_STRUCT(s) s->print_fn(s)
I wonder if typedef and #define are the same in c?
typedef obeys scoping rules just like variables, whereas define stays valid until the end of the compilation unit (or until a matching undef).
Also, some things can be done with typedef that cannot be done with define.
For example:
typedef int* int_p1;
int_p1 a, b, c; // a, b, c are all int pointers
#define int_p2 int*
int_p2 a, b, c; // only the first is a pointer, because int_p2
// is replaced with int*, producing: int* a, b, c
// which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp; // func_p is a pointer to a function that
// takes an int and returns an int
No.
#define is a preprocessor token: the compiler itself will never see it.
typedef is a compiler token: the preprocessor does not care about it.
You can use one or the other to achieve the same effect, but it's better to use the proper one for your needs
#define MY_TYPE int
typedef int My_Type;
When things get "hairy", using the proper tool makes it right
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
No, they are not the same. For example:
#define INTPTR int*
...
INTPTR a, b;
After preprocessing, that line expands to
int* a, b;
Hopefully you see the problem; only a will have the type int *; b will be declared a plain int (because the * is associated with the declarator, not the type specifier).
Contrast that with
typedef int *INTPTR;
...
INTPTR a, b;
In this case, both a and b will have type int *.
There are whole classes of typedefs that cannot be emulated with a preprocessor macro, such as pointers to functions or arrays:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Try doing that with a preprocessor macro.
#define defines macros.
typedef defines types.
Now saying that, here are a few differences:
With #define you can define constants that can be used in compile time. The constants can be used with #ifdef to check how the code is compiled, and specialize certain code according to compile parameters.
You can also use #define to declare miniature find-and-replace Macro functions.
typedef can be used to give aliases to types (which you could probably do with #define as well), but it's safer because of the find-and-replace nature of #define constants.
Besides that, you can use forward declaration with typedef which allows you to declare a type that will be used, but isn't yet linked to the file you're writing in.
Preprocessor macros ("#define's") are a lexical replacement tool a la "search and replace". They are entirely agnostic of the programming language and have no understanding what you're trying to do. You can think of them as a glorified copy/paste mechanic -- occasionally that's useful, but you should use it with care.
Typedefs are a C language feature that lets you create aliases for types. This is extremely useful to make complicated compound types (like structs and function pointers) readable and handlable (in C++ there are even situations where you must typedef a type).
For (3): You should always prefer language features over preprocessor macros when that's possible! So always use typedefs for types, and constant values for constants. That way, the compiler can actually interact with you meaningfully. Remember that the compiler is your friend, so you should tell it as much as possible. Preprocessor macros do the exact opposite by hiding your semantics from the compiler.
They are very different, although they are often used to implement custom data types (which is what I am assuming this question is all about).
As pmg mentioned, #define is handled by the pre-processor (like a cut-and-paste operation) before the compiler sees the code, and typedef is interpreted by the compiler.
One of the main differences (at least when it comes to defining data types) is that typedef allows for more specific type checking. For example,
#define defType int
typedef int tdType
defType x;
tdType y;
Here, the compiler sees variable x as an int, but variable y as a data type called 'tdType' that happens to be the same size as an int. If you wrote a function that took a parameter of type defType, the caller could pass a normal int and the compiler wouldn't know the difference. If the function instead took a parameter of type tdType, the compiler would ensure that a variable of the proper type was used during function calls.
Also, some debuggers have the ability to handle typedefs, which can be much more useful than having all custom types listed as their underlying primitive types (as it would be if #define was used instead).
No. typedef is a C keyword that creates an alias for a type. #define is a pre-processor instruction, that creates a text replacement event prior to compilation. When the compiler gets to the code, the original "#defined" word is no longer there. #define is mostly used for macros and global constants.
AFAIK, No.
typedef helps you set up an "alias" to an existing data type. For eg. typedef char chr;
#define is a preprocessor directive used to define macros or general pattern substitutions. For eg. #define MAX 100, substitutes all occurrences of MAX with 100
As mentioned above, there is a key difference between #define and typedef. The right way to think about that is to view a typedef as being a complete "encapsulated" type. It means that you cannot add to it after you have declared it.
You can extend a macro typename with other type specifiers, but not a typedef'd typename:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Also, a typedef'd name provides the type for every declator in a declaration.
#define fruit int *
fruit apple, banana;
After macro expansion, the second line becomes:
int *apple, banana;
Apple is a pointer to an int, while banana is an int. In comparison. a typedef like this:
typedef char *fruit;
fruit apple, banana;
declares both apple and banana to be the same. The name on the front is different, but they are both pointers to a char.
Another reason to use typedef (which has only been mentioned briefly in other answers and yet I think is the entire reason typedef was created) is to make debugging easier when using libraries that have custom types. For example, I'll use a type-conversion error. Both the codes below will print a compile-time error saying that a char is not comparable to a string, but in different ways.
typedef char letter;
letter el = 'e';
if(el == "hello");
The above code will print something like the variable "el" of type letter (aka "char") is not compatable with type "char*"
#define letter char
letter el = 'e';
if(el == "hello");
This code will instead print the variable "el" of type char is not compatable with type "char*"
This may seem silly because I'm defining "letter" as "char", but in more complex libraries this can be extremely confusing because pointers to objects like buttons, windows, sound servers, images, and lots of other things are defined as unsigned char *, which would only be debuggable as exactly that when using the #define method.
As everyone said above, they aren't the same. Most of the answers indicate typedef to be more advantageous than #define.
But let me put a plus point of #define :when your code is extremely big, scattered across many files, it's better to use #define; it helps in readability - you can simply preprocess all the code to see the actual type definition of a variable at the place of its declaration itself.