From: Alan S. <st...@ro...> - 2010-04-09 15:14:42
|
On Fri, 9 Apr 2010, Pete Batard wrote: > Alright, I see the consensus, and I'm not planning to go against it (but > I will still voice my opinion down below). > > So our considerations are that: > > 1. libusb.h should specify a calling convention always, which should be > the most commonly used calling convention for the platform (here > Windows, hence __sdcall/WINAPI, though we might also be able to get away > with __cdecl as long as it's in a header -- and in case there's a > possibility of misinterpretation, I'm not advocating anything here, just > stating). Which one you choose hardly matters. The effect on code size and execution time is going to be pretty small regardless. But it is important that a choice be made. > 2. we should avoid/prevent the production of binaries (DLLs) that don't > use the most commonly used calling convention from the platform (or at > least, the one we set as default in libusb.h). Likewise, all of > MinGW/cygwin/DDK/MSVC should produce a library that use the same calling > convention by default, so that the development environment used to > produce the libusb DLL is interchangeable. Although correct, this point reflects a misconception which I discuss below. > 3. people who use libusb should be able to pick a pre-compiled DLL from > anywhere, and the associated libusb.h (that was used for the > compilation, hence with an explicit calling convention), with the latter > set to avoid being faced with the "is this DLL __sdcall, __cdecl or > other?" issue. > > 4. the defaults for MinGW/cygwin (which we haven't changed yet) and > Visual C++ DLL production (which we have) are deficient because they use > __cdecl which isn't the most widespread calling convention, and are > therefore a disputable choice made by the developers of these > development environments. > > I do hope that this is a fair summary of the points that have previously > been made in this thread. > > > Now, and this is not for the sake of being contradictory, I'm afraid I > personally still have an objection to every single of the points above, > except aspects of #2 (avoid yes, prevent no), but again, I will go with > the overwhelming majority, so you can disregard/ignore the objections > below. And if you feel this discussion is becoming detrimental to the > list, I have no problem pursuing privately with those interested. > > > 1. libusb.h should not specify a calling convention by default, but > instead, people should ensure that they use a DLL that has the default > calling convention that they need with their app. This exposes your misconception in a nutshell. The main point you're not appreciating is this: The calling convention is part of a function's prototype, just like the number and type of its arguments and the type of its return value. Once you have absorbed this, you'll see that it makes no sense for libusb.h not to specify a calling convention. It would be exactly like declaring a function with no parameters in the prototype (as in the original K&R style). Can you imagine a library where the .h file did not specify the number and types of the function arguments, and consequently different developers produced DLLs where the same functions expected different numbers of arguments? The situation is exactly analogous. > Only for calls that > need it specifically (vargs, threads) should a convention be explicitly > specified. To compensate with issues raised with that approach (as I > tried to express, any approach has issues), developers should be able to > easily set the convention and recompile. And the whole point of the PEv2 > discussion was that, through the use of smart compilers, the OS should > be the entity responsible to alert users (and developers) that the DLL > they are trying to use at runtime is not using the calling convention > expected by the application. That's just as silly as expecting the OS to be the entity responsible for warning people that they're calling a function with the wrong number of arguments. > 2. And since the expected objection about similarly named DLLs, that use > different calling conventions if we don't specify one, being overwritten > in system32 and breaking existing application, brings us to the second > point, yes, everybody should have the ability to produce DLLs that use > whatever calling convention they see fit, No they shouldn't. That's like saying they should have the ability to produce DLLs in which the functions take whatever number of arguments they want, instead of the the number of arguments specified by you (i.e., by the libusb developers). (Of course, in reality people _do_ have this ability. You can't stop them from editing your source code however they want. That isn't the point -- they'd be foolish to change your design decisions and expect the results to be intercompatible with anything else.) > 3. People should only be expected to pick DLLs from anywhere if the OS > can address the issue of telling them when they are using calling > conventions that don't match. As long as the OS doesn't do that, and > there is a BOfH possibility, they should refrain from picking up the > first DLL they see to replace an existing one (and no, I don't have a > problem answering the "flood" of "I picked a libusb DLL that doesn't > work!" e-mails then, or providing both a cdecl and stdcall version of > binaries -- which I already do by accident actually). No commercial > application developer would support users who cherry pick critical > application binaries that they haven't vouched for, and it should be the > same with libusb application developers. Once you accept the point above, this becomes a non-issue. > 4. I can't help but finding it strange that 2 very separate group of > people, who should know better, have chosen to use __cdecl as the > default calling convention when producing DLLs, rather than __stdcall. What difference does it make? _Any_ default choice locks people into one mode of operation. Since there is very little advantage to one over the other, why should it be strange that different people have made different choices? The _real_ issue is that the compilers allow people to produce DLLs without explicitly specifying the calling convention of each of the exported functions. _That_'s what causes problems; not selection of one default instead of another. Alan Stern |