

A proposal for named arguments for C++ - cpeterso
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4172.htm

======
StefanKarpinski
Please stop adding features to C++ and standardize an ABI already. The lack of
an ABI is why it's impossible to call C++ libraries without an entire C++
compiler – and it generally requires generating mountains of wrapper code a la
SWIG – which is then called with the C ABI. The lack of an ABI is why dynamic
libraries use C for writing extensions instead of C++: C++ can literally only
be called by C++ (and in fact only by the same C++ compiler).

~~~
jamesaguilar
It's not really the responsibility of the standard committee, right? C also
has no standard ABI.

~~~
StefanKarpinski
C absolutely has an ABI – you do not need a C compiler to call a C library.

~~~
kentonv
Nonsense. C doesn't even define the width of an int, without which an ABI
makes no sense. An ABI is a property of a specific target platform
(architecture and possibly OS); every platform defines its own. Windows and
Linux on x86_64 don't even use the same ABI (the width of "long" is different,
for starters). But both platforms have C++ ABIs just as much as they have C
ABIs.

The problem with C++ ABIs is that C++ A _P_ Is tend to include much more
substantial details in their headers. If you want to call a template or inline
function, then you need a C++ compiler. Fundamentally, though, this is not any
different from C macros -- a macro-heavy C API is going to require a C
compiler to use.

~~~
StefanKarpinski
It's certainly not cross-platform, but in practice you can call C libraries on
a given platform the same way, regardless of which compiler generated them.

~~~
kentonv
You can do that with C++ too -- assuming they are conforming to the platform
ABI. On Linux, for example, all C++ compilers can call each other's code just
fine.

You may be thinking of the funny situation on Windows where GCC has
historically flagrantly disregarded the platform C++ ABI and implemented its
own instead. I assume this decision was made as a matter of practicality: The
Cygwin people didn't have the resources to try to implement Microsoft's ABI,
whereas porting over the existing code for the Linux C++ ABI was a lot easier.
Also, MSVC tends to take much longer to implement new C++ language features
than GCC does which means its ABI could often be missing things GCC needs.

FWIW, Clang's port to Windows is taking the correct approach: they're
implementing Microsoft's ABI, and will thus be able to link against MSVC-built
C++ library.
[http://clang.llvm.org/docs/MSVCCompatibility.html](http://clang.llvm.org/docs/MSVCCompatibility.html)

~~~
hanumantmk
In all fairness, Microsoft breaks abi in the standard library with every
single release. They do so deliberately to reserve the right to improve
implementations over time.

For some evidence:

See an interesting reddit thread:
[http://www.reddit.com/r/cpp/comments/13zex3/can_vs2010_c_lib...](http://www.reddit.com/r/cpp/comments/13zex3/can_vs2010_c_libsdlls_be_linked_into_a_vs2012_c/c78ott7)

And a link to a msvc blog post which lists the sizes of various containers
under various versions of MSVC:
[http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.a...](http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx)

Note that vector<int> on x64 shrunk from 48 to 24 bytes between VC9 SP1 and
VC11. That's not an ABI, it's source compatibility.

~~~
kentonv
True, but that's a different level of ABI. Stefan is talking about the base
language ABI, e.g. calling conventions, vtable layout, etc., which is what
matters if you're trying to call C++ from another language. You're talking
about the ABI of the standard library -- or, more accurately, any library that
uses STL types in its interface (which probably disqualifies it from being
called from another language anyway).

------
backlava
I think they should use this syntax:

void foo(static int name) { ... }

I don't think they're 'static' for anything on parameters yet.

~~~
general_failure
Well played

------
jjoonathan
This is exactly why I like the Objective-C method call syntax. Instead of
"mystery argument soup"

    
    
        rectangle->set(10,10,20,20,true,false)
    

you get something that can be understood without taking a trip to the API
docs:

    
    
        [rectangle setX:10 y:10 width:20 height:20 updateBSP:YES clipToParent:NO]
    

It's a pity they are moving away from this syntax in Swift. It's the right
move -- I hear nothing but hate for it from those who don't actually use it
(i.e. the people who should be Swift's target audience) -- but it's still a
pity.

~~~
Marat_Dukhan
I think C++ should use notation similar to designated initializers (that C++
adapted from C99) for names arguments, i.e. rectangle->set(.x = 10, .y = 20,
.width = 20, .height = 20)

Otherwise, it would be very confusing that two different syntax are used for
similar purpose.

------
robmccoll
One of my favorite C preprocessor hacks - emulating named parameters in C.

[https://gist.github.com/robmccoll/5236408528c8c664c201](https://gist.github.com/robmccoll/5236408528c8c664c201)

~~~
kentonv
If only named member initializers were supported in C++.

Here's a similar hack that works in C++11, though it unfortunately requires
declaring a global variable for each name (which I make less-bad by prefixing
them with $, which is non-standard but supported by all major compilers):

[https://gist.github.com/kentonv/7553792](https://gist.github.com/kentonv/7553792)

~~~
captaincrowbar
I did something similar (without macros, with a bit more type safety since the
keywords have an associated type, and with a shortcut for boolean arguments):

[https://github.com/CaptainCrowbar/kwargs](https://github.com/CaptainCrowbar/kwargs)

------
assignedM
This might sound negative, but I'm really curious why this is needed if you
have an IDE that tells your the parameter names as you're typing and in a
mouseover. If you need it to be more visible, make that a feature in the IDE
to show you the parameter names all the time. Why change the language?

Not only that, but why are you passing so many parameters like top, bottom,
left, right? At least put them in a struct if you can't make them fields of
the object itself.

This feature seems like "too little, too late". Maybe 30 years about it would
have been helpful.

~~~
jws
Optional named parameters with default values can make nice clean calls in the
common case while still allowing for the uncommon case.

As far as the IDE goes, for the sort of code I write, reading is more
important than writing. When I read the code I'd rather see what it does than
what I think it does.

~~~
assignedM
VB used to allow you to omit optional parameters by just leaving it blank

foo(36,,,54)

sure it won't do if there are dozens but for the odd ugly case where you
naughtily use optional parameters it's OK.

It sounds like there's a need for IDEs to show the parameter names all the
time. They could just be inserted automatically into the display if you want
to see them, or turn them off if you don't like that. Better than being always
on like this proposal.

------
etimberg
I like this idea in theory. the rectangle the example is a good one that I've
personally tripped over before.

That being said, this could hurt readability in some cases as single lines of
code are going to get larger, especially with length parameter names. Another
issue I forsee is a code style where parameters are prefixed with p_. Having
to type that prefix each time would be annoying, but finding a readable syntax
that allows a separately specified name will also be confusing.

~~~
rootbear
I agree this probably looks better in theory than it does in practice. As far
as long function declarations go, it sure would be nice to go back to
declaring multiple arguments of the same type without repeating the type:

    
    
      int myfunc(float x, y, z, r, g, b, a);
    

instead of

    
    
      int myfunc(float x, float y, float z, float r, float g, float b, float a);
    

Yes, I know about structs, but often that's not applicable. And if the type
name is some long thing, then you have to really look carefully to notice they
are all the same type. It seems this style is now being seen as a feature,
although I don't know of any language that required repeating the type for
each parameter until C and C++ adopted this for the new style function
prototype declarations. I was very sorry to see that D has also adopted this
"feature". I believe go allows multiple declarations of the same type. I'd
much rather see this fixed in C and C++ than have them clutter up things with
named parameters.

~~~
restalis
"int myfunc(float x, y, z, r, g, b, a);"

This got me thinking of the old C ways: [http://msdn.microsoft.com/en-
us/library/efx873ys.aspx](http://msdn.microsoft.com/en-
us/library/efx873ys.aspx)

------
nkozyra
What's the argument against, well, named arguments? Is it a matter of brevity
versus verbosity?

~~~
jschwartzi
Well, function specifications in the link table would have to become more
verbose, and the linker would have additional decisions to make. You could
also wind up deferring a lot of problems that could be caught by compile-time
checking until link-time, which might also be run-time.

The problem that they're trying to solve is that people often use 5 arguments
when a single struct would do.

~~~
kentonv
No, this proposal does not affect the linker at all. Argument names would be
resolved to positional arguments during compilation.

~~~
jschwartzi
Yes, actually. You're right:

> In this proposal, the association of parameter names with a function for the
> purpose of making calls with named arguments to that function happens
> locally in each translation unit, and new declarations within a translation
> unit can change a function's ability to be called with named arguments at
> call sites below the new declaration (by using different names than a
> previous declaration).

------
frozenport
It is of some note that the order execution/passing of arguments to a C++
function is yet to be defined. For example,

    
    
        Whatdoesitdo (i++, i)

~~~
kenrose
To pick nits, the order _is_ defined: it's defined as being unspecified
(Section 5.2.2).

~~~
frozenport
Undefined is the opposite of defined, and threading in C++98 was `not
considered` or `unaddressed`?

------
aleaonard54
I hate this idea. It just clutters the UI too much and adds noise especially
if it's a UI you're familiar with. The C/C++ language is noisy enough without
all this. Modern IDEs alleviate the need to be reminded inline what the values
are for. On top of the fact, just about every IDE invented in the last 10
years offers code completion making this useless IMHO.

~~~
MereInterest
On the contrary, I would say that it cleans things up amazingly. As the
language currently is, if I want to change one of the default values, I need
to specify every single value up to that point.

    
    
        func(5,0,0,NULL,0,true,true,false,NULL,true);
        func(verbose: true);
    

With named parameters, I can just specify the differences between my function
call and the default values.

~~~
blt
_> func(5, 0, 0, NULL, 0, true, true, false, NULL, true);_

a Windows programmer by any chance? :)

------
mikepurvis
I find the discussion about ABI compatibility to be unsatisfactory.

If I'm reading this correctly, it ends up basically boiling down to a
preprocessor trick; you don't get the advantage of being able to add
parameters to a function, and have name-based calls to it continue to do the
right thing without a recompilation.

------
userulluipeste
How about this:

    
    
      typedef int annotated_type;
      void foo (annotated_type parameter_name) {}
    

then I could write this:

    
    
      foo (5); /* the short and alegedly ambiguous version of function calling */
    

or this:

    
    
      foo ((annotated_type) 5); /* now I know more about what "5" means
                                   in this function parameter's context */
    

There could be a lot of annotated types around, and their presence would be
optional, so the code could be cluttered for the sake of making things more
explicit only where it would be really needed!

Of course, this doesn't come with parameter-order juggling, but that is
another can of worms in itself, which I'd better avoid!

------
superfunc
I'm all for anything that can remove ambiguity from code where it is very
likely. I notice this problem especially when I'm doing game stuff like
collision detection and whatnot.

------
general_failure
Why oh why do we need some parameters be positional and others be named. At
the very least, it should just be one or the other style. Not some mix and
match.

~~~
wtallis
I can easily see a use for having some mandatory parameters followed by a few
optional arguments. Requiring the mandatory parameters to be named adds
verbosity to the code for the sake of slightly simplifying the language, which
doesn't strike me as being a very C++ sort of philosophy.

------
fishnchips
Sure, why not - let's bolt another leg onto that dog ;)

