On 9 Apr 2011 05:34:56 GMT, Jorgen Grahn <grahn+>
wrote:
>On Fri, 2011-04-08, Ben Bacarisse wrote:
>> DSF <> writes:
>>
>>> On 6 Apr 2011 14:19:41 GMT, Jorgen Grahn <grahn+>
>>> wrote:
>>>
>>>>
>>>>Create a
>>>>
>>>>static inline struct bar foo2bar(struct foo val);
>>>>
>>>>and let the optimizer deal with it. With a bit of luck the foo2bar()
>>>>call just melts away into nothing -- as it should.
>...
>
>>> I then use foo2bar wherever I have a "foo" and a "bar" is needed?
>>
>> Not quite. Function calls are not "lvalues" which means (in part) that
>> you can't take the address of the result. So if you need a bar in some
>> context where it's address gets taken, you can use the function call.
>
>I have to confess that I (when I suggested the inline function) was
>influenced by C++. Const references and stuff like that may make the
>function call solution more attractive there than in C.
>
>>> If this is the case, this would cut down on typing, but still
>>> produces more code than I'd like. There wouldn't be a function call,
>>> but the "copy val to r" code would still be created for each "call".
>>
>> I'd have though that depends on the context and the quality of the
>> optimiser but there may be some reason I can't see why it is hard to
>> remove r altogether.
>
>And I should also have added: look at the generated code to see if
>the function call really gets optimized away (if that matters more
>than type safety).
I did, in fact, do this. To venture slightly off topic here, some
X86 code generated passing foo2bar(foo) to function dobar(struct bar).
As in:
; struct foo f;
; struct bar b;
;
; union foobar {
; struct foo f;
; struct bar b;
; };
;
; union foobar fb;
Pass inlined foo2bar to dobar:
; g = dobar(foo2bar(f));
;
mov ecx,dword ptr [ebp-92]
mov dword ptr [ebp-116],ecx
mov ecx,dword ptr [ebp-88]
mov dword ptr [ebp-112],ecx
mov eax,dword ptr [ebp-116]
mov dword ptr [ebp-124],eax
lea eax,dword ptr [ebp-132]
mov edx,dword ptr [ebp-112]
mov dword ptr [ebp-120],edx
mov ecx,dword ptr [ebp-124]
mov dword ptr [ebp-132],ecx
mov ecx,dword ptr [ebp-120]
mov dword ptr [ebp-128],ecx
push dword ptr [eax+4]
push dword ptr [eax]
call @dobar$q3bar
add esp,8
mov dword ptr [$abhiflaa],eax
Pass the bar part of union foobar to dobar:
; g = dobar(fb.b);
;
push dword ptr [ebp-104]
push dword ptr [ebp-108]
call @dobar$q3bar
add esp,8
mov dword ptr [$abhiflaa],eax
As you can see, the inlined call produces a *LOT* more code: It
basically just inlines the member copy.
>
>>> The above prototype and function compile fine as C++, but produce
>>> syntax errors unless "inline" is removed.
>
>And yes, I was assuming C99.
>
>/Jorgen
|