Function declarations/defaults

B

Billy Patton

In c can I declare a default value for an function argument?

int X(int a,int b=10);

int main()
{
X(1);
}

int X(int a,int b)
{
printf("a = '%d' , b = '%d'\n",a,b);
}

___ _ ____ ___ __ __
/ _ )(_) / /_ __ / _ \___ _/ /_/ /____ ___
/ _ / / / / // / / ___/ _ `/ __/ __/ _ \/ _ \
/____/_/_/_/\_, / /_/ \_,_/\__/\__/\___/_//_/
/___/
Texas Instruments ASIC Circuit Design Methodlogy Group
Dallas, Texas, 214-480-4455, (e-mail address removed)
 
T

T.M. Sommers

Billy said:
In c can I declare a default value for an function argument?

int X(int a,int b=10);

int main()
{
X(1);
}

int X(int a,int b)
{
printf("a = '%d' , b = '%d'\n",a,b);
}

Not in C.
 
A

Andreas Kahari

In c can I declare a default value for an function argument?

No, not in the same way as in C++. You could possibly simulate
it in a crude way by means of arrays or variable length argument
lists.
 
A

Alan Connor

printf("a = '%d' , b = '%d'\n",a,b);
}

___ _ ____ ___ __ __
/ _ )(_) / /_ __ / _ \___ _/ /_/ /____ ___
/ _ / / / / // / / ___/ _ `/ __/ __/ _ \/ _ \
/____/_/_/_/\_, / /_/ \_,_/\__/\__/\___/_//_/
/___/
Texas Instruments ASIC Circuit Design Methodlogy Group
Dallas, Texas, 214-480-4455, (e-mail address removed)


You are spamming the Usenet.

By leaving off the sig delimiter "-- " that allows people to not-view
sigs if they want to.

This is truly slimy.

And sigs are limited

to the four lines immediately below the delimiter.

Killfiled for 30 days.

Clean up your act.
 
K

Kevin Bracey

In message <[email protected]>
"T.M. Sommers said:
Not in C.

This keeps coming up. Was any thought put into adding this during the C99
development process? As C++ features go, it's one of the simplest, and it's
easy to implement. I know there are lots of times when I'd have found it
useful.

Similarly, C++'s unnamed parameters would be nice. Those two features fall
firmly into the "better C" part of the C++ brief, rather than being part
of all that weird OO stuff. They're also simpler (from the implementor's
point of view) than some of the new C99 stuff, like compound literals.
 
J

Jack Klein

R

Richard Heathfield

Jack said:
What was wrong with the answers you got when you posted the same
question a week ago?

He left them out on the table instead of putting them back in the
refrigerator, and they've gone stale.

Typical newbie.
 
D

David M. Wilson

Kevin Bracey said:
This keeps coming up. Was any thought put into adding this during the C99
development process?

I thought the purpose of the standardisation process was to harmonise
existing implementations. I don't know of any C compiler that allows
default arguments.

As C++ features go, it's one of the simplest, and it's
easy to implement. I know there are lots of times when I'd have found it
useful.

I find one of the biggest beauties of C to be it's raw explicitness.
Save a handful of automatic type conversion rules and optimising
compilers, there is very little that goes on under the hood that you
are not aware of.

I occasionally use default arguments in Python, but I find that most
of the time my use of them can either be avoided, or be found
confusing.

Similarly, C++'s unnamed parameters would be nice.

What are unnamed parameters? (C++ clubie here) :)


David.
 
C

Chris Torek

What are unnamed parameters? (C++ clubie here) :)

I am sure Kevin Bracey means the syntactic trick for indicating
that a formal parameter exists only "pro forma". Imagine, for
instance, a key/value interface for a hash table:

void insert(struct hashtab *ht, char *key, char *value);

and then an actual implementation in which only the "key" part
matters, so the values are ignored:

void insert(struct hashtab *ht, char *key, char *value) {
/* code here that uses "ht" and "key", but not "value" */
}

Good compilers often produce warning messages about unused
parameters; to shut them up, one currently can resort to
compiler-specific tricks such as:

value; /* shut up warning */

or:

void insert(struct hashtab *ht, char *key,
char *value _Pragma("unused")) {

or:

void insert(struct hashtab *ht, char *key,
char *value __attribute__((unused))) {

(this last is actual, and rather horrible, gcc syntax -- the double
parentheses and lack of string-literal-ness are why I consider it
"horrible"; the C99 folks got this one right). It might be nice
to allow:

void insert(struct hashtab *ht, char *key, char *) {

as a syntax in actual definitions. As far as parsing and function
typing go, omitting the parameter's name in an actual definition
would work in the same way as omitting it in a prototype declaration,
but it would also serve as a clear signal that the parameter is
deliberately unused.

(Deliberately-unused parameters generally occur more often in
"object-oriented" interfaces, so the insert() function might
be found via a table of operations:

/* "valueless" hash functions - lookup returns only "" or NULL */
static char *lookup(struct hashtab *, char *key);
static void insert(struct hashtab *, char *key, char *value);
static void delete(struct hashtab *, char *key);
struct hash_ops valueless_hash = { lookup, insert, delete };

and the caller would be ignorant of the "valuelessness" of the
hash, just making calls like:

table->ops->insert(table, key, value);

Note that defining a standard "unused argument" _Pragma would work
just as well as adding C++-like syntax.)
 
D

David M. Wilson

Chris Torek said:
void insert(struct hashtab *ht, char *key,
char *value __attribute__((unused))) {
(this last is actual, and rather horrible, gcc syntax -- the double
parentheses and lack of string-literal-ness are why I consider it
"horrible"; the C99 folks got this one right).

Just a quick note on the rationale behind the double parenthesis. IIRC
I read this in the gcc infotex..

The double parens allow __attribute__ to be defined as a
single-argument macro on non-gcc systems, like so:

#ifndef SOME_GCC_FLAG
# define __attribute__(x)
#endif

Making:

char *value __attribute__((ugly))

Become:

char *value

On non-gcc systems, thus allowing gcc-specific code to be compiled on
these systems, although obviously with a loss of functionality. So
there you have it, although it's ugly as hell, there is at least some
half-decent rationale behind it. :)
</useless-info>


David.
 
C

Chris Torek

Just a quick note on the rationale behind the double parenthesis. IIRC
I read this in the gcc infotex..

The double parens allow __attribute__ to be defined as a
single-argument macro on non-gcc systems, like so:

#ifndef SOME_GCC_FLAG
# define __attribute__(x)
#endif

Ah, but the same would have applied had __attribute__ taken a
string literal. Had __attribute__ been defined like C99's _Pragma:

void insert(struct hashtab *ht, char *key,
char *value __attribute__("unused")) {

one could then use:

#ifndef SOME_GCC_FLAG
# define __attribute__(x) /* empty; remove x */
#endif

Moreover, this fixes a serious problem implementors had with GCC's
"noreturn", "pure", and "format printf". Suppose I, as the provider
of <stdlib.h>, <stdio.h>, and so on, want to declare some function
as "not returning" or "printf-like" (or even both, such as the 4.4BSD
err() and errx(), though there are no Standard C functions that are
both). Suppose I have stdlib.h include the line:

void exit(int) __attribute__((noreturn));

This is all well and good so far, but now suppose a C programmer
writes -- as is her right -- code like this:

#define nodeposit 9
#define noreturn 72

#include <stdlib.h>

Suddenly my __attribute__ line reads, after preprocessing:

void exit(int) __attribute__((72));

which produces an error during compilation.

At some point GCC was modified to add double-underscore versions
of all the attribute names, so that I can write:

void exit(int) __attribute__((__noreturn__));

4.xBSD's err() is, for instance:

void err(int, const char *, ...)
__attribute__((__noreturn__, __format__((__printf__, 2, 3))));

(Admittedly, since this is in the nonstandard <err.h> header, I --
the implementor -- can simply decree that the programmer must not
#define away any of the identifiers "noreturn", "format", and
"printf". But personally I find this restriction ugly and tacky.)
Compare this with my suggested variant:

void err(int, const char *, ...)
__attribute__("noreturn, format(printf, 2, 3)");

(GCC's section("section-name") attribute gets ugly instead,
assuming one takes one's cue from C99. Here we might have
_Pragma("section(\"blah\")") to put a function in the "blah" section.
Then again, there is no reason to require the quotes inside the
parentheses as long as section names are forbidden to contain
parentheses, bringing us back to _Pragma("section(blah)").)
... So there you have it, although it's ugly as hell, there is at
least some half-decent rationale behind it. :)
</useless-info>

Indeed. Perhaps now that C99 is out, the GNU folks will pick up
on the _Pragma idea, and re-adopt all their __attribute__s as either
_Pragmas or __attribute__-with-string-literal. (The Extremely
Magical Double Parentheses Syntax makes it technically possible to
shoehorn string literals in as well, without breaking backwards
compatibility. I once took a look at what it would take to implement
this, though, and decided it was ugly enough that I would never
get the FSF to buy it back.)
 
K

Kevin Bracey

I thought the purpose of the standardisation process was to harmonise
existing implementations.

*Cough* restrict. *Ahem* static array arguments. *Splutter* imaginary types.

And what about, horror, function prototypes? Some deviant committee members
went and put those in from C++, and it's been downhill ever since :)
 
T

Thad Smith

Chris said:
Good compilers often produce warning messages about unused
parameters; to shut them up, one currently can resort to
compiler-specific tricks such as:

value; /* shut up warning */

or:

void insert(struct hashtab *ht, char *key,
char *value _Pragma("unused")) {

or:

void insert(struct hashtab *ht, char *key,
char *value __attribute__((unused))) {

Two more for your collection:
(void) value;
and
if(value);

required by two compilers I have used.

The specific code is wrapped in an system-dependent UNUNSED_VAR() macro.

Thad
 
C

CBFalconer

Kevin said:
(e-mail address removed) (David M. Wilson) wrote:
.... snip ...

*Cough* restrict. *Ahem* static array arguments. *Splutter*
imaginary types.

And what about, horror, function prototypes? Some deviant
committee members went and put those in from C++, and it's been
downhill ever since :)

Oh my. You are the model of a modern major reactionary :)
 
A

Andreas Schwab

Chris Torek said:
Moreover, this fixes a serious problem implementors had with GCC's
"noreturn", "pure", and "format printf". Suppose I, as the provider
of <stdlib.h>, <stdio.h>, and so on, want to declare some function
as "not returning" or "printf-like" (or even both, such as the 4.4BSD
err() and errx(), though there are no Standard C functions that are
both). Suppose I have stdlib.h include the line:

void exit(int) __attribute__((noreturn));

You don't, use __attribute__((__noreturn__)). Works with every attribute.

Andreas.
 
C

Chris Torek

Chris Torek said:
Moreover, this fixes a serious problem implementors had with GCC's
"noreturn", "pure", and "format printf". ... [note the past tense]
... Suppose I have stdlib.h include the line:
void exit(int) __attribute__((noreturn));

You don't, use __attribute__((__noreturn__)). Works with every attribute.

It does *now*, as I noted below in the same article.

(It did not work in gcc 2.3.x. Luckily, for exit(), the attribute
could be spelled "__volatile__" as well. But this did not work for
format(printf) and format(scanf).)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top