__MATHCALLX (ceil,, (_Mdouble_ __x), (__const__));
Rev: 1507
Path: /trunk/src/sdk/gcc-attribs.h
Author: thomasdenk
Age: 2 days
Log message:
Changed gcc attribute macros to lowercase for better readability.
Changed likely() and unlikely() so they work with arbitrary values.
Added some more attribute macros.
Added attributes to the block allocator and to code completion.
Marked Manager::isappShutingDown() as deprecated.
Don't we love SVN? :)Yes.
Anyway, why is Code::Blocks even using gcc extensions? Using compiler specific things (especially compiler specific extensions) is a very bad practice (at least in my opinion). Is there any reason why Code::Blocks now uses them? It should be a very very good one - or I'll be rather disappointed. 8)This is easily explained. I introduced gcc extensions because they are there, and because you can use them. It is bad practice to use them if you do not take provisions that you can still use other compilers, but these were taken. The macros evaluate to a gcc attribute definition when compiled with gcc, and to an empty string in all other cases. I do not see that as bad practice, I see it as making use of features which are useful. For example, if(unlikely(ptr == 0)) gives valuable hints to the compiler - the branch for the null pointer is almost never taken, and gcc is able to optimize the code accordingly. On compilers other than gcc, unlikely(x) evaluates to (x), so you don't really give away anything.
From revision 1502 on a file named 'src/sdk/gcc-attribs.h' entered the project. At first this seems to be no problem but in revision 1507 there were massive changes to this file. One of the changes was adding the makro __const__. This breaks (at least vor me) the codestats plugin (and possible more - it could even break the whole project. Seems as this didn't happen yet, I fear it could do it when nobody would expect it.). The problem is: The file '/usr/include/bits/mathcalls.h' contains lines like the following:CodeNow guess what happens :?__MATHCALLX (ceil,, (_Mdouble_ __x), (__const__));
GCC throws lots of weired error messages. Error messages that seem to have no sense at all.
That is the best example why praeprocessor macros are evil. It took me two hours to find the reason for that problem.
Anyway, why is Code::Blocks even using gcc extensions? Using compiler specific things (especially compiler specific extensions) is a very bad practice (at least in my opinion). Is there any reason why Code::Blocks now uses them? It should be a very very good one - or I'll be rather disappointed. 8)
Also, wxWidgets is notorious about defining really sick macros (#define new) and using attributes incorrectly.First, it can be disabled with wxUSE_GLOBAL_MEMORY_OPERATORS.
Urxae is right, never define something starting with an _ (underscore) or __ (double underscore), because those are reserved for usage by the implemetator of the standard library, so it's probable to have name clashes.
Now back on topic:
Saying that wxDEPRECATED(x) is harder to read is an opinion. In my view, is better because: it's capitalized, and it notes that the entire macro is applied.
However all of thatisn't that important compared to this:
While your someFunction() cbDEPRECATED works on GCC, it doesn't work on Visual C, because the declaration is inverted cbDEPRECATED someFunction().
So, putting everything into a macro argument like wxDEPRECATED(x) is the only solution.
D:\Temp>cat test.cpp
void __attribute((deprecated)) f() {}
int main()
{
f();
}
D:\Temp>g++ test.cpp
test.cpp: In function `int main()':
test.cpp:5: warning: `f' is deprecated (declared at test.cpp:1)
test.cpp:5: warning: `f' is deprecated (declared at test.cpp:1)
It's ok if GCC supports that then. But are you sure that works on any gcc version?No, some of these attributes only work with gcc version >= 3.
And you'll certainly will want to hope that no other compiler handles that in a different way.
With the other way however, you don't have to worry about future/other compilers.
Replaced double-underscore macros with triple-underscore due to problems encountered with codestats plugin.
In C, the implementation reservesC++ additionally reserves any name containing __ anywhere in it, not just at the beginning.
- any global-scope name beginning with _
- any name beginning with _ followed by an upper-case letter
- any name beginning with __
I vote for cbEVILMACRO convention.
Lest someone pronouces fo(u)rth, I removed gcc attributes.
// Attributes and builtins used when compiling Code::Blocks with gcc
// No effect (short of being documentary) with other compilers
//
// $Id$
#ifndef GCC_ATTRIBS
#define GCC_ATTRIBS
#if __GNUC__ >= 3 // ----------------------------------
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)
#define compiler_constant(x) __builtin_constant_p(x)
#define cpu_prefetch(x) __builtin_prefetch(x)
#define cbINLINE __attribute__ ((always_inline))
#define cbNOINLINE __attribute__ ((noinline))
#define cbNOTHROW __attribute__ ((nothrow))
#define cbDEPRECATED __attribute__ ((deprecated))
#define cbCONST __attribute__ ((const))
#define cbPURE __attribute__ ((pure))
#define cbCHECKRESULT __attribute__ ((warn_unused_result))
#define cbMALLOC __attribute__ ((malloc))
#ifdef __WIN32__
#define cbFASTCALL __attribute__ ((fastcall))
#define cbFASTESTCALL __attribute__ ((regparm(3)))
#else
#define cbFASTCALL
#define cbFASTCALL
#endif
#else // ----------------------------------
#define likely(x) (x)
#define unlikely(x) (x)
#define compiler_constant(x) false
#define cpu_prefetch(x)
#define cbINLINE inline
#define cbNOINLINE
#define cbNOTHROW
#define cbDEPRECATED
#define cbCONST
#define cbPURE
#define cbCHECKRESULT
#define cbMALLOC
#define cbFASTCALL
#define cbFASTCALL
#endif // ----------------------------------
#endif
The keyword inline is not that interesting, since it is just a hint to the compiler !!!So what do you want to tell me? Functions defined inside the class scope are only inlined in optimized build.
Secondly, methods being implemented within the class definition/body are , according to the standard, to be inlined !!!
Methods implemented in the class body are ALWAYS inlined (I think this is guranteed by the standard) !!!
[...] Otherwise, when you specify -O, member functions defined inside class scope are compiled inline by default
Methods implemented in the class body are ALWAYS inlined (I think this is guranteed by the standard) !!!Correction: functions defined inside a class definition are inline-qualified.
class MyClass
{
void MyFunction1() const {return something;} // <<---- always inlined
inline void MyFunction2(); //<<-- implemented somewhere else (90% chance this inline suggestion will be ignored)
}
Inline Difficulty: 4 / 10
Contrary to popular opinion, the keyword inline is not some sort of magic bullet. It is, however, a useful tool when employed properly. The question is, When should you use it?
This one is a matter of judgment. In short, prefer to write all functions out-of-line by default, and then selectively inline individual functions as necessary only after you know that the performance gain from inlining is actually needed.
If you inline the function, the positive side is that you avoid the overhead of the extra function call to f.
The negative side is that inlining f exposes f's implementation and make client code depend on it, so that if f changes all client code must recompile. Worse, client code now also needs at least the prototype for function g(), which is a bit of a shame since client code never actually calls g directly and probably never needed g's prototype before (at least, not as far as we can tell from our example). And if g() itself were changed to take other parameters of still other types, client code would now depend on those classes' declarations, too.
Both inlining or not inlining can be valid choices. It's a judgment call where the benefits and drawbacks depend on what you know about how (and how widely) f is used today, and how (and how often) it's likely to change in the future.
From the GotW coding standards:
- prefer passing parameters of class type by const& rather than passing them by value
- avoid inlining functions until profiling tells you it's justified (programmers are notoriously bad at guessing which parts of their code are performance bottlenecks)