To use Perl like conditional assignment in C

Y

Ya Shou

Hello,


I want to assign an uncertain value to a variable, this variable with
values in the configuration file, reads the configuration file
through a function to return to the read configuration value, if not
configured or the value of non-compliance, will return 0 for failure,
when this, I will to give it a default value assigned.

However, I found it seem impossible to achieve this in C, but much
easier to implement in Perl, see below:

cfgval = loadConfig () || DEFAULT_VAL;

In C '||' operator does not return the value of the expression which
is true, but returns 1 or 0, so that I can not be used in a similar
way. I considered a program in C is:

cfgval = loadConfig ()? loadConfig (): DEFAULT_VAL;

And however, this approach to involve a duplication of code, it is
ugly, the other will call loadConfig function twice, inefficient and
likely to cause unnecessary accidents.

Of course, if / else statement can achieve this functionality, but
this method requires an additional variable, and not look simple. As
follows:

int loadval = loadConfig ();
if (loadval! = 0) {
cfgval = loadval;
} else {
cfgval = DEFAULT_VAL;
}

Or

int loadval;
cfgval = (loadval! = 0)? loadval: DEFAULT_VAL;


I would like to ask you is, in this case, there is nothing more
beautiful realization?


Thanks.
 
W

Willem

Ya Shou wrote:
) Hello,
)
)
) I want to assign an uncertain value to a variable, this variable with
) values in the configuration file, reads the configuration file
) through a function to return to the read configuration value, if not
) configured or the value of non-compliance, will return 0 for failure,
) when this, I will to give it a default value assigned.
)
) However, I found it seem impossible to achieve this in C, but much
) easier to implement in Perl, see below:
)
) cfgval = loadConfig () || DEFAULT_VAL;
)
) In C '||' operator does not return the value of the expression which
) is true, but returns 1 or 0, so that I can not be used in a similar
) way. I considered a program in C is:
)
) cfgval = loadConfig ()? loadConfig (): DEFAULT_VAL;
)
) And however, this approach to involve a duplication of code, it is
) ugly, the other will call loadConfig function twice, inefficient and
) likely to cause unnecessary accidents.
)
) Of course, if / else statement can achieve this functionality, but
) this method requires an additional variable, and not look simple. As
) follows:
)
) int loadval = loadConfig ();
) if (loadval! = 0) {
) cfgval = loadval;
) } else {
) cfgval = DEFAULT_VAL;
) }
)
) Or
)
) int loadval;
) cfgval = (loadval! = 0)? loadval: DEFAULT_VAL;
)
)
) I would like to ask you is, in this case, there is nothing more
) beautiful realization?

Why can't you assign to cfgval twice?

if (!(cfgval = loadConfig()))
cfgval = DEFAULT_VAL;

Or if you want to mimic the Perl style:

(cfgval = loadConfig()) || (cfgval = DEFAULT_VAL);

But that will be deemed very ugly by most C programmers.

IIRC, some compilers have an extension which allows this:

cfgval = loadConfig() ?: DEFAULT_VAL;

But that is not standard C, as far as I know.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
E

Eric Sosman

Hello,


I want to assign an uncertain value to a variable, this variable with
values in the configuration file, reads the configuration file
through a function to return to the read configuration value, if not
configured or the value of non-compliance, will return 0 for failure,
when this, I will to give it a default value assigned.
[...]

Others have suggested ways to write this. But is it a good
idea? It leaves you with no way for the configuration file to
supply zero as an actual value, which may be satisfactory now
but could become troublesome later.

"In-band" signalling has a long history, and you'll find it
used a lot in the C library and in C programs. The malloc()
function returns NULL to indicate a special case, and this works
because NULL is easily distinguishable from any valid pointer.
strchr(), getenv(), and many others use NULL in a similar way.
But with functions returning other types it's not always so easy
to choose an "impossible" value. time() and several other time-
related functions return -1 when something's wrong, but on most
systems the value -1 could easily be understood as a perfectly
valid time, often 1969-12-31 23:59:59. fgetc() returns the value
EOF, which is supposed to be different from all actual character
values -- but this makes trouble on systems with wide characters
and narrow integers, or on ones' complement or signed magnitude
systems where `char' is signed. strtol() uses three different
"impossible" values, *all* of them perfectly legitimate!

In short, using a special value to mean "absent" or "invalid"
may seem convenient, but can be less convenient than it appears
at first. Instead of

cfgval = loadConfig();
if (cfgval == SPECIAL_VALUE)
cfgval = DEFAULT_VALUE;

consider something more like

if (!loadConfig(&cfgval))
cfgval = DEFAULT_VALUE;

where loadConfig() tries to load the value and store it at the
indicated place, and returns 1 or 0 to indicate success or failure.
Or, if you prefer, use

cfgval = loadConfig(DEFAULT_VALUE);

where loadConfig() loads and returns the value from the configuration
file, or returns its own argument if unable to load anything. You
could even put DEFAULT_VALUE into loadConfig() itself, producing

cfgval = loadConfig();

where loadConfig() loads and returns the file's value if it can, or
returns DEFAULT_VALUE if unable.

But think long and hard and critically before using SPECIAL_VALUE.
It can become a snare and a delusion.
 
W

Willem

Eric Sosman wrote:
) Or, if you prefer, use
)
) cfgval = loadConfig(DEFAULT_VALUE);
)
) where loadConfig() loads and returns the value from the configuration
) file, or returns its own argument if unable to load anything. You
) could even put DEFAULT_VALUE into loadConfig() itself, producing
)
) cfgval = loadConfig();
)
) where loadConfig() loads and returns the file's value if it can, or
) returns DEFAULT_VALUE if unable.

I prefer the first, because of the more real-world generic version:
cfgval = loadConfig('foo_num', FOO_DEFAULT_VALUE);

Which I've used plenty of times.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
U

Uno

cfgval = loadConfig ();
if (cfgval == 0) {
cfgval = DEFAULT_VAL;
}

pete,

you just posted another syntax other than c tonight in clc; watch it,
there, revolutionary.
 
B

BartC

However, I found it seem impossible to achieve this in C, but much
easier to implement in Perl, see below:

cfgval = loadConfig () || DEFAULT_VAL;
I would like to ask you is, in this case, there is nothing more
beautiful realization?

Can you change loadConfig()? If so, just do:

cfgval = loadConfig(DEFAULT_VAL);

If you can't change it, use a wrapper:

cfgval = your_loadConfig(DEFAULT_VAL);

or just:

cfgval = your_loadConfig();
 
Y

Ya Shou

I want to assign an uncertain value to a variable, this variable with
values in the configuration file, reads the configuration file
through a function to return to the read configuration value, if not
configured or the value of non-compliance, will return 0 for failure,
when this, I will to give it a default value assigned.
[...]

     Others have suggested ways to write this.  But is it a good
idea?  It leaves you with no way for the configuration file to
supply zero as an actual value, which may be satisfactory now
but could become troublesome later.

     "In-band" signalling has a long history, and you'll find it
used a lot in the C library and in C programs.  The malloc()
function returns NULL to indicate a special case, and this works
because NULL is easily distinguishable from any valid pointer.
strchr(), getenv(), and many others use NULL in a similar way.
But with functions returning other types it's not always so easy
to choose an "impossible" value.  time() and several other time-
related functions return -1 when something's wrong, but on most
systems the value -1 could easily be understood as a perfectly
valid time, often 1969-12-31 23:59:59.  fgetc() returns the value
EOF, which is supposed to be different from all actual character
values -- but this makes trouble on systems with wide characters
and narrow integers, or on ones' complement or signed magnitude
systems where `char' is signed.  strtol() uses three different
"impossible" values, *all* of them perfectly legitimate!

     In short, using a special value to mean "absent" or "invalid"
may seem convenient, but can be less convenient than it appears
at first.  Instead of

        cfgval = loadConfig();
        if (cfgval == SPECIAL_VALUE)
            cfgval = DEFAULT_VALUE;

This is a better way to do that, but twice assignment maybe
superfluous.
consider something more like

        if (!loadConfig(&cfgval))
            cfgval = DEFAULT_VALUE;

I think that is a perfect solution. beautiful and so efficient.
 
K

Keith Thompson

pete said:
Uno said:
Uno wrote:
On 9/24/2011 4:48 AM, pete wrote: [...]
cfgval = loadConfig ();
if (cfgval == 0) {
cfgval = DEFAULT_VAL;
}


you just posted another syntax other than c tonight in clc; watch it,
there, revolutionary.

I don't think that I did that.

Because perl is a child of c,
or that if you thought what you posted was
C, it wouldn't be syntactical?

I just posted some C code.
If it also happens to be some other code,
I don't know anything about it.

Neither does Uno. The code fragment you posted is C; it's not Perl.
 
J

Jorgen Grahn

.
In short, using a special value to mean "absent" or "invalid"
may seem convenient, but can be less convenient than it appears
at first. Instead of

cfgval = loadConfig();
if (cfgval == SPECIAL_VALUE)
cfgval = DEFAULT_VALUE;

consider something more like

if (!loadConfig(&cfgval))
cfgval = DEFAULT_VALUE;

I'd like to recommend

int cfgval = loadConfig(&error);
if (error)
cfgval = DEFAULT_VALUE;

which lets you initialize 'cfgval' at its declaration (and in may
cases make it const).
But think long and hard and critically before using SPECIAL_VALUE.
It can become a snare and a delusion.

Agreed.

/Jorgen
 

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

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top