Last update March 7, 2012

Doc Comments /
Function



Difference (last change) (no other diffs, normal page display)

Deleted: 206,316d205
jam tangan
jam tangan murah
jam tangan kw
hostgator coupon
kata mutiara
Jasa SEO
EZido
RDAnet
pioneer deh-1300mp
asus a53e-xa2
asus tf101-b1
asus tf101-a1
asus n53sv-eh72
asus republic of gamers g74sx
asus acer a5250
acer chromebook ac700
asus asus 53u
lg infinia 55lw5600
Sonicview 360 premier
asus 7 cu ft freezer
asus 30 single wall oven
brother cs6000i sewing machine
brother 1034d serger
brother sewing machines
Yokohama Geolandar H/T-S
crib tent tots in mind
kidco peapod plus
foscam fi8910w
samsung pl120 review
gopro helmet cam
Canon SX130IS
powershot s100
ContourHD 1080p
canon vixia hf r21
digital picture frame
canon ef 50mm f1.4
canon ef 70-300mm review
wide angle lenses
moving comfort sports bra
moving comfort bra
womens argyle sweater
bebe dresses
ViewSonic VX2250WM
Le Pan TC 970
Apple MacBook Air MC965LL
Sennheiser CX 880
plantronics cs540
ultrasonic jewelry cleaner
Sennheiser RS120
bose quietcomfort 15 acoustic noise cancelling headphones
logitech harmony one remote
logitech harmony 900
sony mhc-ec69i
sony mhcec909ip
bose wave music system
sony htss380
logitech squeezebox touch
sony dvp-fx970
onkyo tx-nr509
onkyo tx - nr609
onkyo ht-s3400
energy 5.1 take classic home theater system
polk audio psw505
onkyo ht-s5400
onkyo tx-nr709
belkin pf60
onkyo ht-rc360
denon avr-1912
Yamaha YHT-S400BL
fujitsu scansnap s1500
brother hl-2270dw
epson workforce 545
hp laserjet p2055dn
bushnell 8mp trophy cam
toshiba 32c110u
panasonic viera tc-p60s30
VIZIO E220VA
hauppauge wintv dcr-2650
Acer AM3970-U5022
Acer AspireRevo AR3700-U3002
Dell Inspiron i570
Dell GX620
Gateway FX6860-UR20P
Western Digital My Passport Essential SE 1 TB USB 3.0
Fujitsu ScanSnap S1300
Epson Perfection V300
Fujitsu SCANSNAP S1100
NeatDesk Desktop Scanner and Digital Filing System
Epson WorkForce Pro GT-S50
Kodak P811BK
Epson Perfection V330
Viewsonic VX2453MH
Asus VE228H
ViewSonic VA2431WM
Samsung B2230
HP 2711x
ASUS ML228H
Epson PowerLite Home Cinema 8350
Optoma PK301
Epson EX7210
Epson EX5210
ViewSonic PJD5133
Acer X1161P
FAVI RioHD-LED-2
Epson EX3210
ViewSonic PJD6531w
Trinity 360 Breville 800JEXL
Skil 3320-02
Delta 46-460
Grizzly G0555
Delta 18-900L

Functions    

Table of contents of this page
Functions   
Messages   
Virtual Functions concerns   
Pure Virtual Functions   
Portability and Variadic Functions   
Nested Functions   
How in/out/inout Works With Arrays   
How C Function Pointers Differ from D Function Pointers and Delegates   
The bare() function   
Links   

Messages    

Function parameters, sound, clear and clean

I'm new to D. I think D is a great idea, a much needed thing. But I find its specs are terribly sketchy. With sketchy specs D can't go anywhere, I think.

Here is an attempt of mine to establish sound, clear and clean specs in a simple area to start: function parameters.

I read parameters in D could be of sort "in", "out", "ref", "lazy", "final", "const", "immutable, and "scope", but I see almost no definitions of these.

This is what I get so far:

in - Function gets value but no access to the external variable related to it.

out - Allows update of original external variables but first there's an innitial reset of them.

ref - Not explained here. "Tango w/D" says this is like "out" (access to the original variable) but without changing their values before entering the body of the function.

lazy - Apparently this applies only to parameters that are references to functions (or to expressions that somehow are packed in a function-like manner). It ensures those functions or expressions are executed ("evaluated") only if, when, and as many times, as the code inside the function body requests it.

scope and others - I find no explanations about what will imply to qualify a parameter with these.

But OK, I get at least what some of the intentions are.

Question: Can't all the above be achieved just by having the option of adding a one-character token (say the semicolon ';') somewhere in the parameter list of the function?

The semicolon would divide the list in two zones: first the "input" and then the "input-output" zone. If there is no ';', all would be input.

All variables in the input zone would be of the classical "by value" type. If an object in this zone is big, the compiler should know not to copy it and use a reference to constant (the original variables will contribute their values and it won't be possible to change them in the function body).

And in the second zone all would be references, with complete access to the original variables. If there would be some advantage (I've never had need of this) of resetting some of those variables before entering the body of the function, then that could be done manually or applying some keyword, like "reset" or "init", to the corresponding parameter.

About those "lazy" function-expresion references, that behaviour is just what is commonly needed, it should be the default. Maybe an optional "run" command could be implemented to be added to the reference *in the function calls*, to have it the other way too if desired.

It would look like this:

storclass rettype funcid( inparams ; outparams ){ body }

This seems to me what essentially would be a huge improvement over C/C++ and surely over other languages too, in reference to types of function parameters.

If there is any serious inconveniences to this way I propose, or something that I'm missing, let's talk about it. And come to conclusions, and leave it clearly established.

If there are other functionalities in this area that are worth while, someone should describe and justify them *clearly and completely*. So other additions could be eventually incorporated and then they would also be *clearly established*.

I repeat, with sketchy specs D can't really move ahead. I think.

Virtual Functions concerns    

I think the "Virtual Functions" example has a few problems, mostly with the abc functions (one is declared private in A, and another is declared in B).
  1. How can the test function even "see" abc?
  2. The comment on abc in B seems to miss a point: it's not that A.abc is not virtual, it's that A.abc is not even visible! Also, it says that B.abc is virtual, which implies that even in this simple example, D is unable to "prove it can be made non-virtual".
Suppose you allow/support the useful feature of dynamically loading images. Suppose that new image defines a derived class which overrides a function. What happened to any proof that the base class's function "can be made non-virtual"?

Pure Virtual Functions    

Pure virtual functions are marked with the abstract attribute (see DigitalMars:d/attribute.html )

  class C {
    abstract int f();
  }

Portability and Variadic Functions    

The current information is DMD-specific, and not portable to GDC (and any other D compilers?)

"_argptr" should be of the type std.stdarg.va_list and one must use the templates in there. Manipulating it as a pointer is *not* portable. The offical page should show using templates.

Under "Variadic Functions With Type Info" it says "An additional hidden argument with the name _arguments and type TypeInfo?[] is passed to the function. _arguments gives the number of arguments and the type of each, enabling the creation of typesafe variadic functions." but perhaps that should end with "enabling the creation of variadic functions with type safety" so that it's not confused with the actual "Typesafe Variadic Functions" feature.

Nested Functions    

(by Vincent Thorn) Example after words "Nested functions can be accessed only if the name is in scope" contains error:

void A()

   {
     B();   // ok
     C();   // error, C undefined
   }
Call to function B() is NOT OK! Cause for internal scope compiler looks for definitions in physical order. OF COURSE it must be done like in module scope - in ANY order! And notification about lexical order must be first because people can miss this important point.

How in/out/inout Works With Arrays    

There should be a clear indication of how in/out/inout works with arrays. Someone discovering that arrays are first-class objects may be tempted to think that, if an array is passed as in, then the function cannot modify the array. The current behaviour is consistent with the fact that dynamic arrays have reference semantics; however, I can see that some may either overlook it or wonder if arrays are an exception with more intuitive behaviour.

Something along the lines of this:

For dynamic array parameters, which have reference semantics, the in/out/inout applies only to the address and length of the array, not to its contents. Therefore, a function that has a dynamic array as an in parameter can modify the contents of the array in place. If a dynamic array is an out or inout parameter, the function can also set the argument to point to a new array or change its length.

Source: NG:digitalmars.D/5468

This diagram might be useful as well:

http://bayimg.com/NaeOgaaCC

How C Function Pointers Differ from D Function Pointers and Delegates    

The first thing to remember is that C function pointers are simply pointers to some address in memory. They contain, in their type data, information about the arguments and the return type, but at runtime, they are just a pointer like any other pointer. You can cast a function pointer to a void* and then get the address of the function in memory, for example. Likewise, you can cast a void* back to a function pointer.

D function pointers are the same thing. They are a simple, single pointer.

When you call a function pointer in either language, the code puts your arguments (if any) onto the stack, and then makes a subroutine call to whatever address is stored in the function pointer.

The only difference between D and C function pointers is that (in some architectures) the calling convention may be different. There are various assumptions made by each language (who saves copies of registers, who cleans up the stack, the order of arguments on the stack, etc.) which may vary from language to language. The point of

 extern(C)
is to inform the D compiler that it is talking to a C function, and so it must talk like a C function. This may be different than D's conventions.

This is why you can't store a pointer to a D function in an extern(C) function pointer, or vice-versa. If the function pointer is declared extern(C), then you are saying that the compiler should use C calling conventions when it calls the function. If it is actually a D function, then things will break. To solve this, you implement a trivial wrapper function, which calls the function pointer. It serves as an interpreter between the D function and the C function. You can use wrappers in either direction; to store a pointer to a C function in a D function pointer, then create a D wrapper which calls the C function; the opposite also works.

Delegates are another beast. They are a bit of a conceptual jump, but once you get used to them you'll never want to go back. Delegates are actually two pointers stored in a single variable. One of the pointers is a function pointer to a D function; the other is a void*. When you call a delegate, it passes the void* as the implicit first argument. This is exactly like how class member functions are called.

Think about how a class member function works. Look at this example:

 class Foo {
    int val;
    int foo() { return val; }
 }
 int bar(Foo f) { return f.val; }
The functions Foo.foo() and bar(Foo) are pretty much the same function. The class member function has an implicit argument (Foo) which is automatically passed when you call the member. So the code below, which calls the two functions, is almost identical when you get down to the bare metal:

 Foo f = new Foo;
 ...
 int x = f.foo();
 int y = bar(f);
Delegates work the same way. They just carry around the "this" pointer hidden inside the delegate. So this delegate:

 int delegate() dg = *f.foo;
is pretty much the same thing as this struct:

 struct my_delegate {
    int function(void*) func;
    void *ptr;
 };
 my_delegate my_dg;
 my_dg.func = cast(int function(void*))&bar;
 my_dg.ptr  = cast(void*)f;
And calling the delegate:

 int a = dg();
is just like calling the function pointer with the stored argument:

 int b = my_dg.func(my_dg.ptr);
I would highly recommend that, in your D programs, you always use a delegate any time that you might think about using a function pointer. They are far more flexible; if you ever, in the future, decide that you needed a delegate, they are there. You can always write a wrapper function which turns a function into a delegate:

 int myFunc();
 int delegate() dg = &myFunc();
 	/* syntax error, can't save funcptr in a delegate */
 int delegate() dg = delegate int() { return myFunc(); }
 	/* ok! */
(Technically, you've created a stack delegate above. The 'ptr' of the delegate is actually a pointer to the current stack frame...but since we don't ever use any stack variables, we don't care about the fact that the stack frame isn't valid later on.)

The only complexity here is that if you have a function pointer variable and you have to turn it into a delegate. Then you have to write a tiny struct, and take a delegate from a member function of that struct:

 int delegate() ConvertFuncPtrToDelegate(int function() func) {
    struct Storer {
      int function() func;
      int Call() { return func(); }
    };
    Storer *temp = new Storer[1];
    temp.func = func;
    return &temp.Call();
 }
Source: From NG:digitalmars.D/13707

The bare() function    

All compilers have a predefined piece of code that preceeds the main() function to set everything up prior to main. Sometimes it is required to write your own (not often but sometimes). The concept of the bare() function would be to define the entry point for the application, a function with no preceeding code.

pragma(entry_point, 0x03000000);   // Set the entry point
void bare()
{
    // Set up the stack

    // Set up the heap

    // Do any initialisation

    int rtn = main();

    // Pass return  to the OS

}

Links    


FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: March 7, 2012 20:24 (diff))