So,in a separate compilation simulation environment, there will be two circumstances: some having the prototype, and some not. The LRM could certainly give semantics for both conditions, but would that be enough? Am I right in saying that the only cases where a prototype might exist but not be visible to the caller are the call sites where a hierarchical name is used to reach the function? Does it make sense to deny this feature to hierarchical references? The failures for missing arguments would be clear enough. 1) The semantics where no prototype is available would have to link to a wrapper capable of injecting any defaults that are needed. 2) If symbols in the default expressions must resolve in the caller's scope, then the caller will have to provide an appropriate callback wrapper to every function it calls without a prototype - and it needs to call that function's generic wrapper, not the raw function. 3) If those symbols resolve in the declaring scope for the function, then the wrapper can handle them directly. It is probably not wise to let the outcome depend upon whether the prototype was visible or not. But if the semantic choice turned on whether the call crossed a hierarchy boundary, that might be a clear enough distinction. Having both semantic choices yield good (but potentially different) behavior might be a bit error prone. But then, cross module references also raise the spectre of homonyms with different prototypes, right? So we've already settled the question of programming morals, we're just negotiating the price ;-) Asked to vote today, I'd go with saying cross-module calls evaluate the default arguments in the called module's scope. This encapsulates each instance in which the function is declared to be useable. Reaching in from outside, you are forced to use the function on terms set by the provider. On the one hand, a rich prototype confers real software engineering power. On the other, it weaves a implementation and script-dependent web of dependences between separate compilations. This issue resembles the ones that arose surrounding extern module declarations with aggregate port prototypes. Greg Steven Sharp wrote: > If I understand the C++ situation correctly, a compiler can implement it > simply by filling in any missing arguments to the call at the call site, > using the defaults it has been given interpreted in the calling context. > It is just a convenient shorthand, equivalent to manually filling in the > missing arguments lexically. It only works if the compiler is guaranteed > to have seen a prototype for the function with the default argument values. > > This is an invalid model to use for SystemVerilog, since the compiler is > NOT guaranteed to have seen a prototype or any other declaration for the > function or task when compiling a call to it. In the general case, there > is no way to fill in the defaults during separate compilation of the call. > The only compilation that is guaranteed to have seen the defaults is the > compilation of the task or function. If we want to have defaults that are > interpreted in the context of the caller, then we should apply defaults > only when the compiler has seen a prototype or declaration containing the > defaults. > > Steven Sharp > sharp@cadence.com > >Received on Fri Mar 4 18:58:40 2005
This archive was generated by hypermail 2.1.8 : Fri Mar 04 2005 - 18:59:06 PST