6 ms·
Preprocessor magic: Default Arguments in C
- haberman 15y ago> The advantages of having default arguments is not something that needs convincing. It's just very nice and convenient to have them. The Google Style Guide disallows default arguments, and I find their rationale convincing enough that I never use default arguments in my own code: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Default_Arguments http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
- gaius 15y agoDefault parameters are more difficult to maintain because copy-and-paste from previous code may not reveal all the parameters I am surprised this is an issue at Google.
- gcp 15y agoOne of the more typical ways to figure out how to use a complex API is usually "look at examples".
- Arelius 15y agoWhy? Google, like most companies, Google is made up mostly ofretty standard. Most programmers enjoy referencing existing code to help understand how an interface works. Just because they have more stringing hiring practices doesn't make their engineers some superhuman level of programmer.
- mistercow 15y agoReferencing existing code is one thing. Copy/pasting that code, or writing new code based on it, without actually looking at the documentation to know what you're doing, is another thing entirely.
- Arelius 15y agoThe issue is not what tends to be the correct way to properly code, but how in fact people end up coding. It seems that many engineering decisions are made at google, to minimize the amount of damage a particular programmer can do. This suggests that while Google does/may have some very good people running the place, they also have quite a few programmers whom are mediocre at best. These choices are about building an environment that forces a programmer to do things the right way, rather then expecting them to do such on their own.
- mistercow 15y agoI really don't find that convincing at all. Default arguments are one of the most effective ways of removing boilerplate and making code easier to read and write. Bad programmers will be bad programmers no matter what, and copy/pasted code that the coder doesn't understand will be fragile or broken no matter what. The problem with this reasoning is contained in this: > to force programmers to consider the API and the values they are passing for each argument rather than silently accepting defaults they may not be aware of. All you will force poor coders to do will be to fudge the arguments until the code "works". This is actually worse than the default arguments scenario, because the defaults are more likely to be acceptable than the first value the coder stumbles upon that makes the function go.
- haberman 15y agoFor me it has nothing to do with bad programmers. It has to do with not having "hidden" input to a function. For example, consider a parsing function that has a boolean parameter indicating whether the parsing is "strict" or not. If you make this parameter have a default, it would be easy to use this function (or read code that uses it) without even realizing that the function can operate in more than one "mode." There is no indication at the call site what mode it is operating in, and indeed if the default value is flipped in the header file the caller could change behavior with no code change at the call site! Taking a line from the Python philosophy: "explicit is better than implicit."
- ajross 15y agoC++ is filled with hidden input. The identity of the this pointer is hidden from the execution of the function. The identity of the function to be executed is hidden from the caller. If that's really your requirement, then you're using the wrong language, the ship sailed. I agree with mistercow: default arguments are, on the whole, a Good Thing. Think of them as a restricted form of overloading which requires (much!) less code to be written. Obviously they can be misused, but again, that's the nature of programming (and especially of C++). Sane default argument conventions make code easier to read and write.
- Symmetry 15y agoI don't know, I think I find the Google Python Style Guide just as persuasive in the opposite direction. http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Default_Argument_Values http://google-styleguide.googlecode.com/svn/trunk/pyguide.ht... The reason I would tend to use default arguments in Python and C but not in C++ would be that it can get confusing if you throw in C++'s function overloading. A function by its very nature can't help but have default behavior, and if someone realizes they need to override the defaults they'll probably end up in the documentation or function definition or some other place that will let them realize they can adjust the defaults.
- Xurinos 15y agoI think it is inconsistent with the idea of allowing the instantiation of classes with default constructors, classes whose member variables may be given default values by the constructors.
- Arelius 15y agoThey call it pre processor magic because it's difficult to maintain. Years ago, after writing an OR! Using C pre processor magic, I took a vow: Never again! Do yourself a favor, either write clean, portable, clear and concise C code, or use a real pre-processor. The only time you should be using pre processor magic anyways is in a large project that's not a library anyways. So at that point it's pretty trivial to just use a proper pre-processor.
- cube13 15y agoPreprocessor magic is pretty much required if you want to write multiplatform code. I work on code for Solaris, Linux, and Windows, and makes life much easier to use #defines to standardize the OS calls.
- dpark 15y ago"#define somefunc _someplatformfunc" isn't exactly preprocessor magic. That's just basic preprocessor functionality. "Magic" is the stuff that no one else looking at the code understands, and it's complicated and generally fragile and frankly unnecessary.
- ori_b 15y agoOr you write platform specific code in it's own files, and link it in conditionally. port-linux.c port-win32.c port-solaris.c myprog.c and just compile/link port-$TARGET.c into your program. The code tends to be cleaner, and the platform knowledge is concentrated in one place.
- Arelius 15y agoIn my experience this is a much better approach. Most modern compilers can inline across linker boundaries anyways, so it's not a real performance issue either.
- LefterisJP 15y agoYes having platform specific code in its own header source and just #ifdef the includes provides much cleaner and nicer code
- 0xABADC0DA 15y agoThis is kind of neat to get named arguments in C as well. Instead of calling: foo_init(1, 'a', 1.0); You can write: foo_init(.arg1=1, .arg3=1.0, .arg2='a'); foo_init(.arg3='c'); // etc edit: didn't see this in the blog comments, wasn't trying to steal credit ;-P
- deleted 15y ago[deleted]
- LefterisJP 15y agoHello, I am the author of the linked blog. Your idea is indeed very neat too. Refer to the comment made in the blog by Jens Gustedt. It has lots of potential imo
- cygx 15y agoThe combination of compound literals and variadic macros is indeed pretty neat. It can also be used to implement Java-style variadic functions (ie when the variadic parameters have a single type): #define sum(...) \ sum_(sizeof ((int []){ __VA_ARGS__ }) / sizeof (int), (int []){ __VA_ARGS__ }) int sum_(size_t count, int values[]) { int s = 0; while(count--) s += values[count]; return s; } You'd call the macro as int s = sum(1, -32, 5);
- LefterisJP 15y agonice idea!
- snorkel 15y agoBah. I prefer poor man's currying instead, just wrap the function.
- LefterisJP 15y agoHey all, I am the author of the linked blog. Many nice comments in here, but may I start by a question of my own about hackernews itself. I had submitted this link myself 6 days ago after making the post. Can a link be resubmitted multiple times? The title was a bit different but the link was the same. I am new to the site and want to learn the way it works. As for the comments by many people, it's a given that this will not appeal to all. Heck to most people especially C++ only programmers it will look ugly. The fact is that if for one reason or another you want to provide functions that have default arguments this is a neat and nice way that works for C99. As for needing default arguments, well there might be cases where having them is just a way to spoil or even confuse the programmer. But consider an API. An API of a GUI library. Do you REALLY want to be giving all the customizations offered by the library for every single widget/element? Or do you want a TextBox of size(100,100) at position(200,50) and you are done by letting the default arguments handle all the rest?
- rcfox 15y agoIt looks like the submitter added a & to the end of the URL. This is generally considered to be cheating. I guess it worked out this time though... There are probably a few articles out there that will tell you the best time to submit a link. If you're really worried about getting karma/clicks, you should consult one of them.
- LefterisJP 15y agoNo no, I don't care about karma, just discovered the site recently and wanted to learn how it works. Exposure on the other hand is always a nice thing. I am actually really glad to the submitter since this generated a nice discussion in the blog itself and made me fix a few things I was wrong about.
- aidenn0 15y agoc99 makes this much, much easier than they think: #define ARG_16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,...) q #define COUNT(...) ARG_16(x,##__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) #define PASTE2(a,b) a ## b #define CALLFN(name,nargs,...) PASTE2(name,nargs)(__VA_ARGS__) #define FOO(...) CALLFN(foo,COUNT(__VA_ARGS__),__VA_ARGS__)
- LefterisJP 15y agoAs I told you inside the comments in the blog itself, what is x in the definition of COUNT(...) ? Also it seems that you did not read the topic correctly because even if you tried to apply such a method it would fail for the no arguments case, which is a big part of the bulk of the first method. If I don't get something please feel free to explain