0

Someone could tell me if this code:

int a = 1;
int b = 0;
if (likely(a >= b))
    return 1;

make the same this other?

return (likely(a>= b))

thank so much for the help.

anna coobs
  • 111
  • 5
  • for a definition of `likely`, see http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel-how-do-they-work-whats-their – DaBler Aug 30 '16 at 18:21
  • Very likely the same. But you must treat the returned value as boolean. – Weather Vane Aug 30 '16 at 18:23
  • 1
    Well, it depends on what happens when not `a >= b`... – GManNickG Aug 30 '16 at 18:27
  • @WeatherVane, he doesn't need to treat the returned value as boolean, as `likely()` only returns two possible values (`1` and `0`), and as such the return value will be included in the premise `return 1;`. The code is not exactly the same, as in case `likely()` returns `0`, the code continues past the `return` statement, and no more info has been provided. So the two statements are not equivalent. – Luis Colorado Sep 01 '16 at 07:29
  • @LuisColorado we don't know what `likely()` returns, it is not shown. – Weather Vane Sep 01 '16 at 17:18
  • @WeatherVane, look for the `__builtin_expect(x, y)` definition in https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html and see how it returns the value of its first argument. – Luis Colorado Sep 01 '16 at 20:54
  • @LuisColorado your link does not contain any function named `likely`. In any case the first paragraph says *we do not recommend general use of these functions*. – Weather Vane Sep 01 '16 at 21:05
  • @WheatherVane, you are right... it contains the definition of `__builtin_expect(x, y)` as it is what expands the `likely()` macro definition in the link posted in one of the first comments. Take the time to read there and come back to the link I posted for the complete thing. – Luis Colorado Sep 01 '16 at 21:12
  • @LuisColorado this question is not tagged Linux. My comment, similar to others, was the difference between `likely` returning an `int` value which might not be either `0` or `1`. Although I did explore Linux, I have no interest, at the moment in Linux, no matter how many people think that Linux extensions are good, and Windows extensions are bad. I don't care if your car is "better" than mine. – Weather Vane Sep 01 '16 at 21:18
  • @WeatherVane, Have I mentioned Linux anyway? where? It's not tagged `gcc` and the definition of `__builting_expect(x, y)` is gcc specific. The question talks about the `likely()` function, and one comment provides the definition... What is the reason of your flame? are you disgusted somewhat with my comments? – Luis Colorado Sep 01 '16 at 21:25
  • @LuisColorado sorry if that was my slip. I was getting annoyed for being taking to task, when from the first few comments at the top, it is plain that I said they are the same only if the return value from the unknown `likely` function is boolean. If there is some arcane definition known only to those who use a particular compiler then mybad. My flame was because I am fed up with those (not you) who pull the "my car is better than yours" routine, "my bolt-ons are good, yours are bad". We use the tools we use, for the reasons we do. – Weather Vane Sep 01 '16 at 21:46
  • @WeatherVane, this was also my first touch with the `likely()` function, there's no reason to not follow the link and try to help, even in case you are not familiar with it. That's actually my case. – Luis Colorado Sep 04 '16 at 16:01
  • @LuisColorado thank you, your link (which does not mention `likely`) now makes sense in the context of the earlier [link from DaBler](http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel-how-do-they-work-whats-their) – Weather Vane Sep 04 '16 at 18:46

2 Answers2

3

likely is not part of the C language. It must be defined somehow by the context of the code where you saw this. (It is probably a macro that expands to a compiler-specific construct that tells the compiler that a >= b is likely to be true, which can help optimization. But from the code you showed, we do not know that for sure.)

Assuming that likely is indeed such a macro, we can remove it and proceed to your actual question:

if (a >= b)
    return 1;

is not the same as

return a >= b;

because they do different things when a is less than b. return a >= b; returns zero when a is less than b, but if (a >= b) return 1; goes on to whatever is below the if-statement when a is less than b.

Two constructs that are equivalent to return a >= b; are

if (a >= b)
    return 1;
else
    return 0;

and

if (a >= b)
    return 1;
return 0;

Most experienced C programmers would rather see return a >= b; than either.

[Addendum: return likely(a >= b); is a peculiar thing to write, because the function is going to return either way, and the code setting up the return value is short, simple, and (often) branch-free. It could conceivably provide a hint to interprocedural optimization, but it would be more natural to express that kind of hint as an annotation on the function prototype, e.g.

extern int fstat(int fd, struct stat *st)
    __attribute__((expected_return_value(0)));

(Note: not a real GCC function annotation as far as I know.)]

zwol
  • 135,547
  • 38
  • 252
  • 361
2

They're not the same, because the first block of code doesn't return immediately when a >= b is false, it continues on with the rest of the function (which you haven't shown). So unless the next line is return 0;, they're different.

With the values of a and b that you give, the whole block of code is simply equivalent to return 1;. But I assume that it's possible for a and b to have different values.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • In the all code there are a else with return 0, so if that case are the same? int a = 1; int b = 0; if (likely(a >= b)) return 1; else return 0 – anna coobs Aug 31 '16 at 18:20
  • Then it's the same. If that's what you meant you should have written it in the question. – Barmar Aug 31 '16 at 19:17
  • @annacoobs, `if (likely(a>=b)) return 1; else return 0;` is indeed equivalent, but as you say, "In the all code there are an else..." cannot be made equivalent, because there can be some *lateral effects* in the *all code* that make them different. They are only equivalent if the *all code* reduces to a "return 0;" after the `if` statement. – Luis Colorado Sep 01 '16 at 07:33