Using a specific library function

I have a problem: I would like to use the abs function of the complex library.

However, I am making an error warning me that the abs function is used #define abs(x) (x > 0) ? x : -(x) #define abs(x) (x > 0) ? x : -(x) .

So, I think the problem comes from my import. Due to the fact that I also include the stdio and stdlib libraries, the compiler can use the abs function defined in one of these libraries.

So my question is: how can I use the abs function of the complex library without removing any import?

Thank you very much for your response.

+4
source share
4 answers

Wrap a pars around it.

 (abs)(whatever); 

This will force the compiler to use the version of the function because the macro no longer matches.

Functional macros work by matching the identifier with the next left character ( . Since we wrapped the function name in parens, instead we have an identifier followed by the right paragraph ) that does not match the macro. Paranas are semantically transparent, but they interfere with macro syntax.

IIRC, it was the C splint controller who taught this to me. When writing the postscript interpreter, I created beautiful short macros to access the stack.

 #define push(o) (*tos++ = (o)) #define pop() (*--tos) 

Which were great to complex parts, where they were part of an expression involving tos . To avoid undefined behavior, I had to create functional versions and use them for these complex spots. For the new design, I completely skipped the macros.


Editing: I have a stunning feeling that this is actually a book by Koleokant (Peter Van Der Linden Deep C Secrets), where I found out about this, and the above situation was where I first needed it. His example IIRC involved putchar or getchar , which are often implemented as both functions and macros according to C implementations.

+15
source

Use #undef

 #include "header1.h" #include "header2.h" #undef abs // remove abs macro x = std::abs(y); 
+6
source

While the few suggestions above are very good, I would take a completely different perspective. This is almost something like windows.h , which causes a "bad" definition of the abs() macro. You should be able to NOT include "windows.h" in a file that does complex math [at least in most types of programs] (I don’t know a single function on Windows that takes complex<T> as an argument, so I'm sure that you don’t need both “complex.h" and "windows.h" in the same source file. This method is called "isolate system dependencies", which is very good.

Look at your code and find where you STRONGLY use the Windows features, and then include only “windows.h” in the files that actually need it. You will probably find that if you use Visual Studio, then windows.h is included as part of stdafx.h, which means that all the interesting macros, etc. Included everywhere because "stdafx.h" is included in ALL source files.

+4
source

Both #undef solutions and brackets will work, but I would recommend something a little stronger, because both of these solutions will require you to do them every time you want to call abs , and the next time you can forget and result in an error.

what can you do:

  • change the name of your function to a less common name: absolute , myAbs , etc.
  • enter the function \ class under the namespace (for C ++ not for C), then the calls will be explicit myNameSpace::abs(x)
  • If this does not work as the comment suggested by me, I would still distort the call in my function:

    type myAbs (type param) {return (abs) (param); }

+1
source

All Articles