Skip to content

Commit f67142d

Browse files
authored
[spec/function] Improve variadic function docs (#4316)
Move `core.stdc.stdarg` sentence to where it's actually used. Make examples runnable, add writeln calls. Add links. Fix link to typesafe variadics. Remove `void*` from `_argptr`. Fixes https://github.com/dlang/dmd/issues/21884. `_argptr` is a pointer, not a reference. Print the class member variables in last d-style example (the old output wasn't the class reference address anyway). D-style variadics can be `@safe` if they don't call `va_arg` (though not very useful). A typesafe variadic parameter must be last.
1 parent 2dbb9e1 commit f67142d

File tree

1 file changed

+41
-33
lines changed

1 file changed

+41
-33
lines changed

spec/function.dd

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,23 +2214,18 @@ $(H4 $(LNAME2 c_style_variadic_functions, C-style Variadic Functions))
22142214
a parameter `...` as the last function parameter.
22152215
It has non-D linkage, such as $(D extern (C)).)
22162216

2217-
$(P To access the variadic arguments,
2218-
import the standard library
2219-
module $(LINK2 $(ROOT_DIR)phobos/core_stdc_stdarg.html, $(D core.stdc.stdarg)).
2220-
)
2221-
2217+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
22222218
---
2223-
import core.stdc.stdarg;
2224-
22252219
extern (C) void dry(int x, int y, ...); // C-style Variadic Function
22262220

22272221
void spin()
22282222
{
22292223
dry(3, 4); // ok, no variadic arguments
22302224
dry(3, 4, 6.8); // ok, one variadic argument
2231-
dry(2); // error, no argument for parameter y
2225+
//dry(2); // error, no argument for parameter y
22322226
}
22332227
---
2228+
)
22342229

22352230
$(P There must be at least one non-variadic parameter declared.)
22362231

@@ -2241,7 +2236,7 @@ $(H4 $(LNAME2 c_style_variadic_functions, C-style Variadic Functions))
22412236
$(P
22422237
C-style variadic functions match the C calling convention for
22432238
variadic functions, and can call C Standard library
2244-
functions like $(D printf).
2239+
functions like $(REF_SHORT printf, core,stdc,stdio).
22452240
)
22462241

22472242
---
@@ -2255,23 +2250,32 @@ $(H4 $(LNAME2 c_style_variadic_functions, C-style Variadic Functions))
22552250

22562251
$(P C-style variadic functions cannot be marked as $(D @safe).)
22572252

2253+
$(P To access the variadic arguments,
2254+
import the standard library
2255+
module $(LINK2 $(ROOT_DIR)phobos/core_stdc_stdarg.html, $(D core.stdc.stdarg)).
2256+
)
22582257

2259-
---
2260-
void wash()
2261-
{
2262-
rinse(3, 4, 5); // first variadic argument is 5
2263-
}
2264-
2258+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
2259+
------
22652260
import core.stdc.stdarg;
2261+
import std.stdio;
2262+
22662263
extern (C) void rinse(int x, int y, ...)
22672264
{
22682265
va_list args;
22692266
va_start(args, y); // y is the last named parameter
22702267
int z;
22712268
va_arg(args, z); // z is set to 5
22722269
va_end(args);
2270+
writeln(z);
2271+
}
2272+
2273+
void main()
2274+
{
2275+
rinse(3, 4, 5); // first variadic argument is 5
22732276
}
22742277
---
2278+
)
22752279

22762280

22772281
$(H4 $(LNAME2 d_style_variadic_functions, D-style Variadic Functions))
@@ -2284,7 +2288,8 @@ $(H4 $(LNAME2 d_style_variadic_functions, D-style Variadic Functions))
22842288
$(P If there are parameters preceding the `...` parameter, there
22852289
must be a comma separating them from the `...`.)
22862290

2287-
$(NOTE If the comma is ommitted, it is a $(RELATIVE_LINK2 variadic, TypeSafe Variadic Function).)
2291+
$(NOTE If the comma is omitted, it is a
2292+
$(RELATIVE_LINK2 typesafe_variadic_functions, Typesafe Variadic Function).)
22882293

22892294
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
22902295
------
@@ -2295,35 +2300,36 @@ $(H4 $(LNAME2 d_style_variadic_functions, D-style Variadic Functions))
22952300
------
22962301
)
22972302

2298-
22992303
$(P Two hidden arguments are passed to the function:)
23002304

23012305
$(UL
2302-
$(LI `void* _argptr`)
2306+
$(LI `_argptr`)
23032307
$(LI `TypeInfo[] _arguments`)
23042308
)
23052309

2306-
$(P $(D _argptr) is a
2307-
reference to the first of the variadic
2310+
$(P $(D _argptr) is a pointer to the first of the variadic
23082311
arguments. To access the variadic arguments,
23092312
import $(LINK2 $(ROOT_DIR)phobos/core_vararg.html, $(D core.vararg)).
2310-
Use $(D _argptr) in conjunction with $(D core.va_arg):)
2313+
Use $(D _argptr) in conjunction with $(REF_SHORT va_arg, core,stdc,stdarg):)
23112314

2315+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
23122316
------
23132317
import core.vararg;
2314-
2315-
void test()
2316-
{
2317-
foo(3, 4, 5); // first variadic argument is 5
2318-
}
2318+
import std.stdio;
23192319

23202320
@system void foo(int x, int y, ...)
23212321
{
23222322
int z = va_arg!int(_argptr); // z is set to 5 and _argptr is advanced
23232323
// to the next argument
2324+
writeln(z); // 5
23242325
}
2325-
------
23262326

2327+
void main()
2328+
{
2329+
foo(3, 4, 5); // first variadic argument is 5
2330+
}
2331+
------
2332+
)
23272333
$(P $(D _arguments) gives the number of arguments and the `typeid`
23282334
of each, enabling type safety to be checked at run time.)
23292335

@@ -2370,12 +2376,12 @@ import core.vararg;
23702376
else if (_arguments[i] == typeid(Foo))
23712377
{
23722378
Foo f = va_arg!(Foo)(_argptr);
2373-
writefln("\t%s", f);
2379+
writefln("\t%d", f.x);
23742380
}
23752381
else if (_arguments[i] == typeid(Bar))
23762382
{
23772383
Bar b = va_arg!(Bar)(_argptr);
2378-
writefln("\t%s", b);
2384+
writefln("\t%d", b.y);
23792385
}
23802386
else
23812387
assert(0);
@@ -2396,18 +2402,20 @@ long
23962402
double
23972403
4.5
23982404
Foo
2399-
0x00870FE0
2405+
3
24002406
Bar
2401-
0x00870FD0
2407+
4
24022408
------
24032409

2404-
$(P D-style variadic functions cannot be marked as $(D @safe).)
2410+
$(P D-style variadic functions cannot be marked as $(D @safe) (if
2411+
they call `va_arg`).)
24052412

24062413

24072414
$(H4 $(LNAME2 typesafe_variadic_functions, Typesafe Variadic Functions))
24082415

24092416
$(P A typesafe variadic function has D linkage and a variadic
2410-
parameter, which is typically an array. When passing component
2417+
parameter, which is typically an array followed by `...`.
2418+
The variadic parameter must be the last one. When passing component
24112419
arguments (e.g. array elements), the variadic parameter is
24122420
implicitly constructed from the given arguments.
24132421
)

0 commit comments

Comments
 (0)