Live data from Hacker News

How to properly use macros in C

pmihaylov.com

31–40 of 52 posts

Re: How to properly use macros in C

#31
post #9

One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). This is false. Lisp is a language, or rather, a family of languages, where macros play a giant role, and the author does not seem to mention them. But again, Lisps generally have more powerful macros than C does - they allow for arbitrary compile-time computation.

Lisp macros directly manipulate the program's abstract syntax tree (in the case of Lisp, it happens to hava a 1-1 relationship to the source code structure). It's more comparable to a web app's html templater than a syntactic macro system like Lisp's.

Re: How to properly use macros in C

#32

> macros can’t be debugged. When you use a function, that function can be stepped through by the debugger. The macro cannot. Looks like the debugger could use some improvement. > A macro is faster than a function. This is false. Macros may be faster in some cases, but I've seen them being slower . I suspect this is because functions have more type information that can help the optimiser. I've tried it with Monocypher…

Also, C99 `inline` functions calls do not neccessarily compile to inlined code, and non-inline functions may or may not be inlined, and in certain cases (most notably tail-call optimizations), will not create new stack frames.

Re: How to properly use macros in C

#33
> When you add the inline keyword in front of a function, you are hinting the compiler to embed the function body inside the caller (just like a macro).

That is not quite the case. The inline keyword has changed to mean multiple definitions are allowed. To quote [1]: " Because the meaning of the keyword inline for functions came to mean 'multiple definitions are permitted' rather than 'inlining is preferred' "

[1] http://en.cppreference.com/w/cpp/language/inline

Re: How to properly use macros in C

#34

> Some compilers offer debug strings in macros, which cannot be used in functions: __FILE__, __LINE__, __func__. But... Of course they can. They are just symbols defined by the compiler, and have nothing to do with being in a macro expansion or not. Heck, they are probably implemented as macro's themselves inside the preprocessor.

What he means is, you want to use them in a macro. You can't get the effect you probably want by using them in a function. Compare:

    #define LOG_ERROR() printf("ERROR at %s:%d\n", __FILE__, __LINE__)
    void logError(void) { printf("ERROR at %s:%d\n", __FILE__, __LINE__); }

Re: How to properly use macros in C

#35
post #13

This isn't wrong but I've got issues with some of the examples, especially the lack of a solution for #2 and #4. #2 is referred to as an unsafe macro because of the multiple evaluation of its arguments. In some cases this is fine but it may need to be documented that the macro is unsafe for future users. It is also entirely possible to convert these macros into safe ones if you're willing/able to use GNU C extensions…

> #2 is referred to as an unsafe macro because of the multiple evaluation of its arguments. In some cases this is fine but it may need to be documented that the macro is unsafe for future users. In the early days of C programming, a naming convention was adopted to warn about this. If you wrote a macro that might have multiple evaluation of its arguments, you named it in UPPERCASE as a warning: #define MIN( a, b ) (…

I really find TEMP_ITEM_LIMIT easier to read than tempItemLimit.

Re: How to properly use macros in C

#36
post #9

One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). This is false. Lisp is a language, or rather, a family of languages, where macros play a giant role, and the author does not seem to mention them. But again, Lisps generally have more powerful macros than C does - they allow for arbitrary compile-time computation.

More readable quote: > One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). Instead of indenting a quote, use: > The quote. or if you want italics to set it off more: > *The quote.*

Thanks, TIL.

Re: How to properly use macros in C

#37
post #9

One strange phenomenon when coding in C is using macros. This is not something which can be seen in other programming languages (other than C++). This is false. Lisp is a language, or rather, a family of languages, where macros play a giant role, and the author does not seem to mention them. But again, Lisps generally have more powerful macros than C does - they allow for arbitrary compile-time computation.

Lisp macros directly manipulate the program's abstract syntax tree (in the case of Lisp, it happens to hava a 1-1 relationship to the source code structure). It's more comparable to a web app's html templater than a syntactic macro system like Lisp's.

It doesn't strictly have a 1-1 relationship because of macros themselves. They're Turing complete, so the same macro can expand into different ASTs based on user input during compilation, presence of any files on the hard drive or even moon phases, so I have to say that this relationship is much more complicated than a simple 1-1. For very simple functions like (lambda (x) (* x x)) this is true, but macros' power greatly complicates it.

Re: How to properly use macros in C

#38

Earlier quoted context omitted.

The goal of this article is not to provide some genuine insight to the topic, but to serve as a publicity stunt for the largest code academy in Bulgaria, dubiously called "Software University". On numerous other occasions their lecturers and trainers have made ridiculously misleading claims about trivial programming stuff. One of their lecturers insisted that the second return in "return; return;" was probably needed…

Well, I'm sorry, but I agree with the lecturer. I've run into this problem myself. In my case I had some cleanup code to run at the end of the function in an error case, so I used "goto fail;" instead of "return;". And then just to be sure it always worked, I put in the "goto fail;" twice!

Gave me a good chuckle.

Re: How to properly use macros in C

#39
post #12

The article is an okay start, but it wasn't written by an expert. It lists some real pitfalls but doesn't provide commonly accepted solutions. Some examples... multiple lines: wrap in do { } while (0) - can use a multiline macro like a function call, terminated with ; or ({foo; bar;}) - multiple lines evaluate to 'bar'... Function calls: - in general anything with side effects could be harmful if evaluated more than…

({ }) is handy but is a GCC extension.

So is "typeof"; "__typeof__" is the standard spelling.

Re: How to properly use macros in C

#40

> Some compilers offer debug strings in macros, which cannot be used in functions: __FILE__, __LINE__, __func__. But... Of course they can. They are just symbols defined by the compiler, and have nothing to do with being in a macro expansion or not. Heck, they are probably implemented as macro's themselves inside the preprocessor.

What he means is, you want to use them in a macro. You can't get the effect you probably want by using them in a function. Compare: #define LOG_ERROR() printf("ERROR at %s:%d\n", __FILE__, __LINE__) void logError(void) { printf("ERROR at %s:%d\n", __FILE__, __LINE__); }

Sure, they are pretty useless in a function. But that doesn't mean that the author can go and use incorrect language. :P
Post reply on HN