Computing > Programming

constant sufixes

<< < (10/10)

SiliconWizard:

--- Quote from: Nominal Animal on October 01, 2021, 07:35:58 pm ---Taken all together, this can produce quite verbose-looking code with (int64_t)(...) and INT64_C(...) mixed in.  Do not let it bother you; such verbosity is sometimes preferable.  And not just for the compiler; it can help us humans too, as reading new code with such notation, even when verbose and on long lines, makes the programmer intent/understanding (of valid ranges for that expression) easier to see and understand.  Code golf may be fun, but it is definitely not practical in real life.

--- End quote ---

I agree. And this is all due to the fact C needs to remain the most efficient possible in most situations. So you need to "instruct" the compiler what it is you really want it to implement.

Sure some could dream of easier arithmetics, not needing to care about types and conversions, and with all expressions always being mathematically correct in all cases; that would almost invariably lead to much less efficient code in general. If you expect that, use another language.

blacksheeplogic:

--- Quote from: Jeroen3 on September 24, 2021, 06:48:08 pm ---inline never has the effect you are looking for. It's better to use the compiler specific options if you want the literal effect of the keyword, like: __attribute__((always_inline)); or __forceinline.

Yes, you lose portability. But when you need to do this you probably are micro-optimizing anyway.

--- End quote ---

In general I don't second guess the compiler but if there's a specific need for it use the compile specific directives and use the preprocessor to deal with it:
#ifdef __GNUC__
   static inline ureg load32(void __iomem *address) __attribute__((always_inline))
#endif

SiliconWizard:

--- Quote from: blacksheeplogic on October 01, 2021, 11:39:49 pm ---
--- Quote from: Jeroen3 on September 24, 2021, 06:48:08 pm ---inline never has the effect you are looking for. It's better to use the compiler specific options if you want the literal effect of the keyword, like: __attribute__((always_inline)); or __forceinline.

Yes, you lose portability. But when you need to do this you probably are micro-optimizing anyway.

--- End quote ---

In general I don't second guess the compiler but if there's a specific need for it use the compile specific directives and use the preprocessor to deal with it:
#ifdef __GNUC__
   static inline ureg load32(void __iomem *address) __attribute__((always_inline))
#endif

--- End quote ---

If you want to *force* inlining with GCC, yes, this is the only thing that will work 100% of the time, even at -O0 optimization level.
(Note: a minor remark here, but GCC yields an error when you define the attribute to a function at the end of the declaration, as you did. You need to put it at the beginning, for some reason.

--- Code: ---error: attributes should be specified before the declarator in a function definition

--- End code ---

I'm not 100% sure, but LLVM/Clang should support this attribute too. Just guessing, as it tends to support a good range of GCC extensions and attributes.

But otherwise, unless you selectively disable function inlining through options, GCC will inline almost every function it can starting at -O1, with or without 'inline', even with or without 'static'. In the latter case, a non-static function will usually be inlined where it's called inside the same compilation unit (source file if you will), AND callable code for this function will also be generated at the same time, which will be the version that gets called outside of its compilation unit. Depending on optimization level though, GCC will inline more or less aggressively. At -O1, I think it will automatically inline only functions that are "small enough", but at -O3, it will inline practically ALL functions, which can lead to significantly larger binaries. I don't know GCC's exact criterions though, and this may change at every new version...

So while "inline" is indeed pretty much ignored by most modern compilers *for call optimization*, the standard, as I quoted, still states that it can be an implementation-defined suggestion to the compiler that the call should be "fast" - without mentioning a particular method. The C standard add two footnotes about it:

--- Quote ---By  using,  for  example,  an  alternative  to the  usual  function  call  mechanism,  such  as  ‘‘inline
substitution’’.  (...)
--- End quote ---

--- Quote ---For example, an implementation might never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration.
--- End quote ---

As it's entirely up to the implementation, of course, it may do nothing as far as optimization is concerned. Which is indeed the case with modern GCC and many other C compilers.
But yes, it's true that a number of C compilers already implemented "inline" well before it got standardized (and its getting included in the std probably comes from this fact, actually), and AFAIR, in older compilers, the keyword was indeed the only way of having the compiler inline a function (when the function could be inlined...), as they would not inline anything on their own.

Navigation

[0] Message Index

[*] Previous page

There was an error while thanking
Thanking...
Go to full version