By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,665 Members | 1,761 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,665 IT Pros & Developers. It's quick & easy.

operators similar to functions?

P: n/a
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
Nov 29 '07 #1
Share this Question
Share on Google+
39 Replies


P: n/a
vlsidesign wrote:
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
It's about convenience, and about readability. Not all
languages have found these to be as important:

(setq x (/ (- (sqrt (* 4 a c)) b) (* 2 a)))

.... is (unless I've botched something) the way the grade-school
"quadratic formula" appears in one fairly durable language that
does not distinguish "functions" from "operators."

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 29 '07 #2

P: n/a
vlsidesign <fo*****@gmail.comwrites:
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
You're right, operators (most of them) are conceptually similar to
functions, and in some languages (but not in C), operators really are
treated as functions. An operator takes operands and yields a result;
a function takes arguments and returns a result.

One difference is syntax; operators such as "+" and "*" mimic common
mathematical notation. Addition *could* have been defined using
functional syntax, so you'd have to write ``add(x, y)'' rather than
``x + y''; the latter is just more convenient. Would you rather write
a + b + c + d
or
add(a, add(b, add(c, d)))
?

Another difference is that operators are built into the langauge,
which means that the compiler has to know exactly how they're
implemented -- and can take advantage of that knowledge. Normally
``x + y'' will be implemented in the generated code by something like
an ADD instruction, not by a subroutine call. (But a compiler can
generate inline code for explicit function calls, and it can generate
a function call for an operator that isn't directly implemented as a
CPU instruction.) Also, the compiler is allowed a bit more freedom to
rearrange expressions involving operators than function calls, which
tends to make for more efficient generated code.

Finally, some operators can do things that couldn't be expressed in a
function definition. For example, a function that takes two arguments
always evaluates both of them; you can't write the equivalent of "&&"
or "||" as a function (at least not in C). The "+" operator can
operate on any numeric type; to do the equivalent with functions,
you'd need a separate function for each type. "sizeof" is actually an
operator (despite being spelled as a keyword rather than as a
punctuation symbol); there's no way to write a function that does the
same thing.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 29 '07 #3

P: n/a
vlsidesign wrote:
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
The distinction between operators and function calls is entirely a
matter of syntax. Any operator could have been implemented by a
function, and any standard library function could have been defined as
an operator. It doesn't really affect the efficiency - a sufficiently
good compiler would generate the same actual machine code, whether C was
defined as supporting a+b or add(a,b).

The key difference is that operators take at most two or three
characters to type, making them easier to type and harder to understand.
Functions, on the other hand, have readable names which are typically a
bit longer than operators, which helps you remember what they do, at the
expense of more typing.

Operators are used for the most basic and frequently used operations, so
that the shorter size saves you a lot of space, and the frequent use
makes them easy to memorize. Functions are used for the more complicated
and less frequently used operations, where the extra size of the
function name costs less, and the infrequent use makes the advantage of
a readable name more important.
Nov 29 '07 #4

P: n/a
James Kuyper <jameskuy...@verizon.netwrote:
vlsidesign wrote:
Operators seem similar to functions. ...

The distinction between operators and function calls is
entirely a matter of syntax. Any operator could have been
implemented by a function, ...
True, but it's not a simple mapping.

The following operators would require special kinds of
functions: ||, &&, ?:

A void cast of an integer expression evaluating to zero
could not precisely emulate a null pointer constant
since it would no longer be a constant expression.

--
Peter
Nov 29 '07 #5

P: n/a
Peter Nilsson wrote:
James Kuyper <jameskuy...@verizon.netwrote:
>vlsidesign wrote:
>>Operators seem similar to functions. ...
The distinction between operators and function calls is
entirely a matter of syntax. Any operator could have been
implemented by a function, ...

True, but it's not a simple mapping.

The following operators would require special kinds of
functions: ||, &&, ?:

A void cast of an integer expression evaluating to zero
could not precisely emulate a null pointer constant
since it would no longer be a constant expression.
We're talking fundamental re-design of the language here; and(a,b) could
have been defined as having the same special characteristics as a&&b has
in the actual C language.
Nov 29 '07 #6

P: n/a
vlsidesign wrote:
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
Also one more thing. A function allows you to encapsulate and reuse
pieces of code and thus encourages structured programming; a language
with operators alone would find this difficult to do, early dialects of
BASIC without subroutine support come to mind.

Nov 29 '07 #7

P: n/a
Eric Sosman wrote:
vlsidesign wrote:
>Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..

It's about convenience, and about readability. Not all
languages have found these to be as important:

(setq x (/ (- (sqrt (* 4 a c)) b) (* 2 a)))

... is (unless I've botched something) the way the grade-school
"quadratic formula" appears in one fairly durable language that
does not distinguish "functions" from "operators."
ITYM:
(setq x (/ (- (sqrt (- (* b b) (* 4 a c))) b)(* 2 a)))

I don't know how to give the other root, I don't know enough LISP to
know what the negation operator is!
Nov 29 '07 #8

P: n/a
vlsidesign wrote:
Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..
I agree with all of the other responses, but:

One thing which hasn't been mentioned so far is operators which change
the values of their operands. For example, it is impossible in C to
write a function:
int increment(int x);
which has the same effect as x++ (or ++x). This is because x is passed
by value to the function, so increment() cannot change the value of x in
the caller's scope. The "obvious" implementation:

int increment(int x) { return x++; }

doesn't work because:

#include <stdio.h>
int main(void) {
int i = 0;
increment(i);
printf("%d\n",i); /* i is still 0 */
return 0;
}

[OT: In C++ this problem is solved by introducing reference types which
allow a pass-by-reference mechanism. Then 'int increment (int &x)
{return x++;}' does exactly what you want. This is an example of how
introducing one feature to a lanugage (operator overloading) may require
the introduction of another feature (reference types).]
Nov 29 '07 #9

P: n/a
jacob navia wrote:
Since basically there is no difference between operator usage
and a function call, there are heretics that propose to use the
simpler operator notation instead of the function call notation
to call functions.

Those heretics (that are looked upon with disdain by the law-abiding
regulars of this group)
Sanity check: Many of the regulars here programme in C++ too, and have
no problem with this approach - when programming in C++.

What they _do_ have is a problem with people trying to discuss it in a C
programming group, as if it were topical.
>But "it is an heresy"
Only in /your/ mind.
>and you should not speak about it here,
correct, since it's C++.
P.S. Of course, if you want a compiler that does this within the
framework of C, you look at the signature below and you can
download it for free.
Ps, advertising is not permitted in CLC, as you full well know, you
spamming bar steward.

Nov 29 '07 #10

P: n/a
Philip Potter wrote:
Eric Sosman wrote:
>vlsidesign wrote:
>>Operators seem similar to functions. They both do something to either
arguments or operands, but are different in their syntax. Operators
seem to be like built-in C functions. It would seem that there is very
important reasons for having operands, and not just functions. Maybe
they are just really powerful and can be used in expressions? Or they
are somehow executed quicker than a function call? I am a newbie, and
curious.. thanks for all the insights to this newsgroup..

It's about convenience, and about readability. Not all
languages have found these to be as important:

(setq x (/ (- (sqrt (* 4 a c)) b) (* 2 a)))

... is (unless I've botched something) the way the grade-school
"quadratic formula" appears in one fairly durable language that
does not distinguish "functions" from "operators."

ITYM:
(setq x (/ (- (sqrt (- (* b b) (* 4 a c))) b)(* 2 a)))

I don't know how to give the other root, I don't know enough LISP to
know what the negation operator is!
When I wrote "unless I've botched something," I must
have been imbued with the prophetic spirit. ;-)

Lisp's negation construct is the same as subtraction,
but with just one argument: (- x). So

(setq x1 (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq x2 (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq disclaimer "Unless I've botched something")

My point was that not all languages work hard to imitate
familiar "formula" notations, and that the O.P.'s realization
that operators and functions are similar is correct: the
differences are linguistic, not "essential."

There's a wide family of languages that imitate a formula
notation (C,FORTRAN, Algol, Pascal, ...), but examples of
"non-formulaic" languages are not hard to find. Lisp is one,
assemblers usually focus on the operations rather than on
formulas, what little I saw of COBOL looked like formulas
transliterated into pidgin English, and somewhere in the high
holy Himalayas of ratiocination you'll find the monasteries
wherein dwell the lamas who can actually read APL.

Let's not poke too much fun at Lisp, by the way. It's
challenging to read (although one gets better with practice),
but there are *no* rules of precedence or associativity (or
their formal-grammar counterparts) to confuse newbies, the
"operator overloading" diatribes never erupt, and indeed it's
trivial to introduce brand-new "operators" at need. That's
a lot of power; the obfuscation may be a worthwhile price.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 29 '07 #11

P: n/a
Eric Sosman wrote:
Philip Potter wrote:
>ITYM:
(setq x (/ (- (sqrt (- (* b b) (* 4 a c))) b)(* 2 a)))

I don't know how to give the other root, I don't know enough LISP to
know what the negation operator is!

When I wrote "unless I've botched something," I must
have been imbued with the prophetic spirit. ;-)
Or experience? :)
Lisp's negation construct is the same as subtraction,
but with just one argument: (- x). So
So (- x) doesn't follow the same pattern as (- x y) (- x y z) and so on
do? I guess it makes sense.
(setq x1 (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq x2 (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq disclaimer "Unless I've botched something")

My point was that not all languages work hard to imitate
familiar "formula" notations, and that the O.P.'s realization
that operators and functions are similar is correct: the
differences are linguistic, not "essential."
Hear, hear. What I have been saying elsethread about operators and
functions being fundamentally different only applies to the C language.
There's a wide family of languages that imitate a formula
notation (C,FORTRAN, Algol, Pascal, ...), but examples of
"non-formulaic" languages are not hard to find.
I knew someone who had a scientific pocket-calculator which used reverse
polish notation. So the key combination to calculate the quadratic
formula would (modulo botching) be:

b - b ^2 4 a c * * - sqrt - 2 a * /

[here the first - is negation, while the rest are subtraction. ^2 is one
operator to do squaring.]

This doesn't even require the parenthesis that Lisp uses! (And is even
less readable.)

The only problem with Reverse Polish notation is that it doesn't allow
Lisp-style variadic functions, though it does allow C-style ones.
Nov 29 '07 #12

P: n/a
Mark McIntyre wrote:
jacob navia wrote:
>Since basically there is no difference between operator usage
and a function call, there are heretics that propose to use the
simpler operator notation instead of the function call notation
to call functions.

Those heretics (that are looked upon with disdain by the
law-abiding regulars of this group)

Sanity check: Many of the regulars here programme in C++ too,
and have no problem with this approach - when programming in C++.

What they _do_ have is a problem with people trying to discuss it
in a C programming group, as if it were topical.
>But "it is an heresy"

Only in /your/ mind.
>and you should not speak about it here,

correct, since it's C++.
So far, fine.
>
>P.S. Of course, if you want a compiler that does this within the
framework of C, you look at the signature below and you can
download it for free.

Ps, advertising is not permitted in CLC, as you full well know,
and even here.
you spamming bar steward.
But this last piece is unnecessary and apes Jacobs own diatribes.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Nov 29 '07 #13

P: n/a
Eric Sosman wrote:
>
.... snip ...
>
Let's not poke too much fun at Lisp, by the way. It's
challenging to read (although one gets better with practice),
but there are *no* rules of precedence or associativity (or
their formal-grammar counterparts) to confuse newbies, the
"operator overloading" diatribes never erupt, and indeed it's
trivial to introduce brand-new "operators" at need. That's
a lot of power; the obfuscation may be a worthwhile price.
Actually I was quite surprised some years ago, when I found that
people thoroughly conversant with Lisp could write amazingly clear
source code in it.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com

Nov 29 '07 #14

P: n/a
Op Thu, 29 Nov 2007 14:38:05 +0000 schreef Philip Potter:
Eric Sosman wrote:
>Philip Potter wrote:
>>ITYM:
(setq x (/ (- (sqrt (- (* b b) (* 4 a c))) b)(* 2 a)))

I don't know how to give the other root, I don't know enough LISP to
know what the negation operator is!

When I wrote "unless I've botched something," I must
have been imbued with the prophetic spirit. ;-)

Or experience? :)
> Lisp's negation construct is the same as subtraction,
but with just one argument: (- x). So

So (- x) doesn't follow the same pattern as (- x y) (- x y z) and so on
do? I guess it makes sense.
> (setq x1 (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq x2 (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
(setq disclaimer "Unless I've botched something")

My point was that not all languages work hard to imitate
familiar "formula" notations, and that the O.P.'s realization
that operators and functions are similar is correct: the
differences are linguistic, not "essential."

Hear, hear. What I have been saying elsethread about operators and
functions being fundamentally different only applies to the C language.
> There's a wide family of languages that imitate a formula
notation (C,FORTRAN, Algol, Pascal, ...), but examples of
"non-formulaic" languages are not hard to find.

I knew someone who had a scientific pocket-calculator which used reverse
polish notation. So the key combination to calculate the quadratic
formula would (modulo botching) be:

b - b ^2 4 a c * * - sqrt - 2 a * /

[here the first - is negation, while the rest are subtraction. ^2 is one
operator to do squaring.]
As, like you wrote below, RPN languages don't usally have variadic
functions, the first - is written as NEGATE in Forth.
This doesn't even require the parenthesis that Lisp uses! (And is even
less readable.)

The only problem with Reverse Polish notation is that it doesn't allow
Lisp-style variadic functions, though it does allow C-style ones.
Agreed.
--
Coos
Nov 29 '07 #15

P: n/a
jacob navia <ja***@nospam.comwrites:
[...]
Since basically there is no difference between operator usage
and a function call, there are heretics that propose to use the
simpler operator notation instead of the function call notation
to call functions.

Those heretics (that are looked upon with disdain by the law-abiding
regulars of this group) propose a sin called "operator overloading"
where you can use the operator notation to call your own functions,
imagine that.

You write this absolutely heretical notation:

result_type operator+(arg_type a,arg_type b);

Then, with suitable definitions of arg_type, the compiler will call
this function instead of doing a normal addition.
[...]

This talk of "heresy" is, of course, complete and utter nonsense.

Operator overloading is neither heretical nor sinful. C is not a
religion. Code that uses features that are not part of standard C is
not sinful, or bad, or even necessarily wrong, it's merely something
other than C.

Ironically enough, operator overloading is actually relevant to the
original poster's question. It's a very nice illustation of how
operators and functions *can* be very similar, and of the fact that
the distinction is more syntactic than semantic (though are are also
some semantic differences). It's a pity that jacob couldn't have made
that point without descending into his usual self-pitying nonsense.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 29 '07 #16

P: n/a

"CBFalconer" <cb********@yahoo.comwrote in message
news:47***************@yahoo.com...
Eric Sosman wrote:
>>
... snip ...
>>
Let's not poke too much fun at Lisp, by the way. It's
challenging to read (although one gets better with practice),
but there are *no* rules of precedence or associativity (or
their formal-grammar counterparts) to confuse newbies, the
"operator overloading" diatribes never erupt, and indeed it's
trivial to introduce brand-new "operators" at need. That's
a lot of power; the obfuscation may be a worthwhile price.

Actually I was quite surprised some years ago, when I found that
people thoroughly conversant with Lisp could write amazingly clear
source code in it.
yes.

the main problem though is that the syntax is not, pretty, and is awkward to
type (absent special text editors).
otherwise, it is not that bad though...

for a calculator language of mine, I ended up doing something bizarre and
forcing infix math and a generally lisp-like syntax together into the same
language, but of course this loses the original point of this thread.

in this lang:
'{+ a b}' and 'a+b' were equivalent (infix was largely handled as
sugarring).

some special cases were handled via spacing rules.
'3-2' or '3 - 2' was different than '3 -2' (this being 2 expressions).
....

otherwise, operators were semantically equivalent to functions (and, this
language has assignable functions, so theoretically operator overloading is
really easy...).
parens were also used, but would serve both as parens, and for indicating
blocks.
(
{print "foo "}
{println "bar"}
)

many other things were done with lists, for example: '[2 -3 4 2+3]'.

....

so, a fairly simplistic, yet still fairly easy to look at and type,
syntax...
originally, I implemented it to work as a "better" language for an
interactive calculator, than making use of guile (me finding it frustrating
for these kind of things, as it is tedius to be sure parens are just right,
....).

but, apart from all this, the language hasn't really gone anywhere...

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com

Nov 29 '07 #17

P: n/a
Keith Thompson wrote:
One difference is syntax; operators such as "+" and "*" mimic common
mathematical notation. Addition *could* have been defined using
functional syntax, so you'd have to write ``add(x, y)'' rather than
``x + y''; the latter is just more convenient. Would you rather write
a + b + c + d
or
add(a, add(b, add(c, d)))
?
Nitpick.

"a + b + c + d" is equivalent to add(add(add(a, b), c), d)

(left-to-right associativity)
Dec 3 '07 #18

P: n/a
Spoon <root@localhostwrites:
Keith Thompson wrote:
>One difference is syntax; operators such as "+" and "*" mimic common
mathematical notation. Addition *could* have been defined using
functional syntax, so you'd have to write ``add(x, y)'' rather than
``x + y''; the latter is just more convenient. Would you rather write
a + b + c + d
or
add(a, add(b, add(c, d)))
?

Nitpick.

"a + b + c + d" is equivalent to add(add(add(a, b), c), d)

(left-to-right associativity)
Good catch, thanks.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 3 '07 #19

P: n/a
Richard Harter wrote:
The "compiler cannot be aware" is the main issue. Technically
you are right and I am wrong - obviously the compiler could
generate checks for the possibility of overflow. However the
compiler is not obliged to do so, and I rather doubt that there
is any production compiler that does.

In short, the responsibility for avoiding overflow rests with the
programmer.
For your information:

lcc-win invoked with the -overflowcheck option will check
each operation that can generate an overflow. Any operation that
does generate one will provoke the end of the program
with an error message.

Richard Harter, cr*@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 4 '07 #20

P: n/a
On Tue, 04 Dec 2007 20:08:08 +0100, jacob navia wrote:
Richard Harter wrote:
>The "compiler cannot be aware" is the main issue. Technically you are
right and I am wrong - obviously the compiler could generate checks for
the possibility of overflow. However the compiler is not obliged to do
so, and I rather doubt that there is any production compiler that does.

In short, the responsibility for avoiding overflow rests with the
programmer.

For your information:

lcc-win invoked with the -overflowcheck option will check each operation
that can generate an overflow. Any operation that does generate one will
provoke the end of the program with an error message.
Does it make sure to exclude unsigned wraparound (which isn't overflow)?
In other words, does a valid C program such as

#include <limits.h>
int main(void) {
unsigned u;
u = UINT_MAX / 2;
u++;
u = UINT_MAX;
u++;
return 0;
}

get accepted and does it run without aborting?
Dec 4 '07 #21

P: n/a
Harald van Dijk wrote:
On Tue, 04 Dec 2007 20:08:08 +0100, jacob navia wrote:
>Richard Harter wrote:
>>The "compiler cannot be aware" is the main issue. Technically you are
right and I am wrong - obviously the compiler could generate checks for
the possibility of overflow. However the compiler is not obliged to do
so, and I rather doubt that there is any production compiler that does.

In short, the responsibility for avoiding overflow rests with the
programmer.
For your information:

lcc-win invoked with the -overflowcheck option will check each operation
that can generate an overflow. Any operation that does generate one will
provoke the end of the program with an error message.

Does it make sure to exclude unsigned wraparound (which isn't overflow)?
In other words, does a valid C program such as

#include <limits.h>
int main(void) {
unsigned u;
u = UINT_MAX / 2;
u++;
u = UINT_MAX;
u++;
return 0;
}

get accepted and does it run without aborting?
Overflow check will be done for SIGNED types only

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 4 '07 #22

P: n/a
On Tue, 04 Dec 2007 21:46:15 +0100, jacob navia wrote:
Harald van Dijk wrote:
>On Tue, 04 Dec 2007 20:08:08 +0100, jacob navia wrote:
>>For your information:

lcc-win invoked with the -overflowcheck option will check each
operation that can generate an overflow. Any operation that does
generate one will provoke the end of the program with an error
message.

Does it make sure to exclude unsigned wraparound (which isn't
overflow)? In other words, does a valid C program such as

#include <limits.h>
int main(void) {
unsigned u;
u = UINT_MAX / 2;
u++;
u = UINT_MAX;
u++;
return 0;
}

get accepted and does it run without aborting?

Overflow check will be done for SIGNED types only
The exact program I posted aborts, reporting an overflow, when compiled
with lcc's overflow checking. I was hoping you'd have tried it.
Dec 4 '07 #23

P: n/a
CJ
On 4 Dec 2007 at 19:08, jacob navia wrote:
lcc-win invoked with the -overflowcheck option will check
each operation that can generate an overflow. Any operation that
does generate one will provoke the end of the program
with an error message.
I believe that shows very bad quality of implementation. It's undefined
behavior, so your compiler can do what it likes, but I think it's much
better to let the program continue (maybe the programmer will check
errno for EOVERFLOW, either way I don't think *any* library, including
the standard library, has any business in aborting programs without
giving the programmer chance to recover).

Dec 4 '07 #24

P: n/a
CJ wrote:
On 4 Dec 2007 at 19:08, jacob navia wrote:
>lcc-win invoked with the -overflowcheck option will check
each operation that can generate an overflow. Any operation that
does generate one will provoke the end of the program
with an error message.

I believe that shows very bad quality of implementation. It's undefined
behavior, so your compiler can do what it likes, but I think it's much
better to let the program continue (maybe the programmer will check
errno for EOVERFLOW, either way I don't think *any* library, including
the standard library, has any business in aborting programs without
giving the programmer chance to recover).
I haven't spelled out all the details. You can redefine this behavior if
you add a function called

void _overflow(int linenr, char *functionname);

What I described above is the default action.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 4 '07 #25

P: n/a
Harald van Dijk wrote:
On Tue, 04 Dec 2007 21:46:15 +0100, jacob navia wrote:
>Harald van Dijk wrote:
>>On Tue, 04 Dec 2007 20:08:08 +0100, jacob navia wrote:
For your information:

lcc-win invoked with the -overflowcheck option will check each
operation that can generate an overflow. Any operation that does
generate one will provoke the end of the program with an error
message.
Does it make sure to exclude unsigned wraparound (which isn't
overflow)? In other words, does a valid C program such as

#include <limits.h>
int main(void) {
unsigned u;
u = UINT_MAX / 2;
u++;
u = UINT_MAX;
u++;
return 0;
}

get accepted and does it run without aborting?
Overflow check will be done for SIGNED types only

The exact program I posted aborts, reporting an overflow, when compiled
with lcc's overflow checking. I was hoping you'd have tried it.
OO0O0OPS

Fixed

The intermediate code generated is:
stmt: ASGNI(addr,ADDU(mem,con1))

Asgn integer (address, Add unsigned(memory, constant 1))

I saw the Asgn integer and forgot to see that the add was an
unsigned add.

I checked all similar construct but that was the only one.

Thanks for this, now lcc-win is a bit better.
(Will be in the next release)

jacob


--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 4 '07 #26

P: n/a
CJ
On 4 Dec 2007 at 22:07, jacob navia wrote:
CJ wrote:
>I believe that shows very bad quality of implementation. It's undefined
behavior, so your compiler can do what it likes, but I think it's much
better to let the program continue (maybe the programmer will check
errno for EOVERFLOW, either way I don't think *any* library, including
the standard library, has any business in aborting programs without
giving the programmer chance to recover).

I haven't spelled out all the details. You can redefine this behavior if
you add a function called

void _overflow(int linenr, char *functionname);

What I described above is the default action.
Isn't it possible to turn this off completely, so that overflow is
silently ignored by default? Or do you have to write a no-op function
called _overflow? I think having a special function like this is likely
to encourage programmers using your compiler to rely on such special
overflow handling and write non-portable code.

But if you must have it, why not use existing mechanisms, for example,
you could send a signal to the program on overflow, and set a global
variable like _overflow_has_occurred so that if the programmer installs
a handler for the signal then he can know whether it was triggered by
your overflow mechanism or not.

Dec 4 '07 #27

P: n/a
CJ wrote:
On 4 Dec 2007 at 22:07, jacob navia wrote:
>CJ wrote:
>>I believe that shows very bad quality of implementation. It's undefined
behavior, so your compiler can do what it likes, but I think it's much
better to let the program continue (maybe the programmer will check
errno for EOVERFLOW, either way I don't think *any* library, including
the standard library, has any business in aborting programs without
giving the programmer chance to recover).
I haven't spelled out all the details. You can redefine this behavior if
you add a function called

void _overflow(int linenr, char *functionname);

What I described above is the default action.

Isn't it possible to turn this off completely, so that overflow is
silently ignored by default?
I am ALWAYS wrong with you. As I said in my message
this is only done when lcc-win is invoked with the
-checkoverflow flag!

It is not ON by default.

Or do you have to write a no-op function
called _overflow? I think having a special function like this is likely
to encourage programmers using your compiler to rely on such special
overflow handling and write non-portable code.
???
But if you must have it, why not use existing mechanisms, for example,
you could send a signal to the program on overflow, and set a global
variable like _overflow_has_occurred so that if the programmer installs
a handler for the signal then he can know whether it was triggered by
your overflow mechanism or not.

Well, this all can be done in YOUR overflow function. Other users
will have other requirements, whatever... This is the most flexible
design.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 4 '07 #28

P: n/a
jacob navia wrote, On 04/12/07 22:44:

<snip optional overflow checking>
I am ALWAYS wrong with you. As I said in my message
this is only done when lcc-win is invoked with the
-checkoverflow flag!

It is not ON by default.
<snip>

Personally, I would say an option to trap on signed integer overflow is
a good thing. So now you know not everyone here always disagrees with
everything you have implemented.
--
Flash Gordon
Dec 5 '07 #29

P: n/a
Flash Gordon <sp**@flash-gordon.me.ukwrites:
jacob navia wrote, On 04/12/07 22:44:

<snip optional overflow checking>
>I am ALWAYS wrong with you. As I said in my message
this is only done when lcc-win is invoked with the
-checkoverflow flag!

It is not ON by default.

<snip>

Personally, I would say an option to trap on signed integer overflow
is a good thing.
<off-topic>
In case anyone else is similarly in the dark, I only recently discovered
the very handy -ftrapv option in gcc.
</off-topic>

--
Ben.
Dec 5 '07 #30

P: n/a
CJ said:
On 4 Dec 2007 at 19:08, jacob navia wrote:
>lcc-win invoked with the -overflowcheck option will check
each operation that can generate an overflow. Any operation that
does generate one will provoke the end of the program
with an error message.

I believe that shows very bad quality of implementation. It's undefined
behavior, so your compiler can do what it likes, but I think it's much
better to let the program continue (maybe the programmer will check
errno for EOVERFLOW, either way I don't think *any* library, including
the standard library, has any business in aborting programs without
giving the programmer chance to recover).
That isn't really a problem, since the behaviour is controlled by a switch
which, presumably, the programmer can choose not to throw. The problem is
not "this switch is bad" so much as "this switch has nothing whatsoever to
do with the topic of this newsgroup". The switch *is*, however, topical in
comp.compilers.lcc, and it would be good for those who wish to discuss it
to do so there, rather than here.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 5 '07 #31

P: n/a
jacob navia said:
CJ wrote:
>On 4 Dec 2007 at 22:07, jacob navia wrote:
>>CJ wrote:
I believe that shows very bad quality of implementation. It's
undefined behavior, so your compiler can do what it likes, but I think
it's much better to let the program continue (maybe the programmer
will check errno for EOVERFLOW, either way I don't think *any*
library, including the standard library, has any business in aborting
programs without giving the programmer chance to recover).

I haven't spelled out all the details. You can redefine this behavior
if you add a function called

void _overflow(int linenr, char *functionname);

What I described above is the default action.

Isn't it possible to turn this off completely, so that overflow is
silently ignored by default?

I am ALWAYS wrong with you. As I said in my message
this is only done when lcc-win is invoked with the
-checkoverflow flag!
This is more properly a subject for comp.compilers.lcc - but it seems to me
that if overflow checking is only done when -checkoverflow is set, then
setting -overflowcheck (which was what you said last time) is a bit
pointless.

si tacuisses...

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 5 '07 #32

P: n/a
On Wed, 05 Dec 2007 09:49:25 +0000, Philip Potter
<pg*@doc.ic.ac.ukwrote:
>Richard Harter wrote:
>On Tue, 04 Dec 2007 10:40:18 +0000, Philip Potter
<pg*@doc.ic.ac.ukwrote:
[snip]
>This is quite true. To quote myself, the responsibility for
avoiding overflow rests with the programmer and not with the
compiler.

When you cannot even add two integers together without avoiding all
possibility of overflow, how do you propose the programmer achieves this?
The programmer does it by not adding two integers together if
their sum would overflow.
>
You give all of the responsibility to the programmer but you do not give
him the tools to fulfill that responsibility.
He has a brain, doesn't he? That's the relevant tool to use.

Richard Harter, cr*@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
The good news is that things could be worse; the bad
news is that things aren't as good as they should be.
Dec 5 '07 #33

P: n/a
RoS
In data Tue, 04 Dec 2007 17:02:37 GMT, Richard Harter scrisse:
>>As a result, a
programmer cannot even add two numbers together without invoking
undefined behaviour.

This is quite true. To quote myself, the responsibility for
avoiding overflow rests with the programmer and not with the
compiler.
.... and the language data structure
Dec 5 '07 #34

P: n/a
Richard Heathfield wrote, On 05/12/07 06:11:
CJ said:
>On 4 Dec 2007 at 19:08, jacob navia wrote:
>>lcc-win invoked with the -overflowcheck option will check
each operation that can generate an overflow. Any operation that
does generate one will provoke the end of the program
with an error message.
I believe that shows very bad quality of implementation. It's undefined
<snip>
That isn't really a problem, since the behaviour is controlled by a switch
which, presumably, the programmer can choose not to throw. The problem is
not "this switch is bad" so much as "this switch has nothing whatsoever to
do with the topic of this newsgroup". The switch *is*, however, topical in
comp.compilers.lcc, and it would be good for those who wish to discuss it
to do so there, rather than here.
In my opinion Richard's comment about topicality is true for CJ's post,
but *not* for Jacob's post. Jacob mentioned the switch to provide an
example of an implementation which does overflow checking in a
sub-thread about the impacts of overflow checking on what is "valid" C,
and as such Jacob's post was perfectly reasonable.
--
Flash Gordon
Dec 5 '07 #35

P: n/a
Flash Gordon wrote:
>
In my opinion Richard's comment about topicality is true for CJ's post,
but *not* for Jacob's post. Jacob mentioned the switch to provide an
example of an implementation which does overflow checking in a
sub-thread about the impacts of overflow checking on what is "valid" C,
and as such Jacob's post was perfectly reasonable.
Yes, that was what prompted me to answer that.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Dec 5 '07 #36

P: n/a
cr*@tiac.net (Richard Harter) writes:
On Tue, 04 Dec 2007 13:43:35 -0800, Keith Thompson
<ks***@mib.orgwrote:
>>cr*@tiac.net (Richard Harter) writes:
>>On Tue, 04 Dec 2007 15:08:28 -0500, Eric Sosman
<Er*********@sun.comwrote:
[...]
>>>>
5.1.2.3, with special attention to paragraph 5.

5.1.2.3 of what? Clearly not Harbison $=& Steele. I'm guessing
that it is from some standard, either C89, C90, or C99.
Whichever it is, I don't have a copy. Would it possible to
actually quote the paragraph in question, or failing that, point
to a publicly readable version on the web.

You asked for a citation from the standard, and when presented with a
section number you're not sure that it refers to the standard?

Yes, it's section 5.1.2.3 of the standard. It could be either C90 or
C99, since that particular setion has the same number in both.

Let me grumble a bit. Just because one is a programmer doesn't
mean that one is exempt from the ordinary standards of
scholarship. Part of the drill is to include the identification
of references.
[...]

Not to beat a dead horse, but the reference was already identified.
Let's look at the context:

Richard Harter wrote:
[...]
| Of course Harbison & Steele could be wrong, or the standard may
| have been amended since then, but the text is quite clear. If
| you disagree with the text feel free to point out where it is
| wrong by citing the appropriate section of the standard.

Eric Sosman replied:
| 5.1.2.3, with special attention to paragraph 5.

You specifically asked for a citation *of the standard*, and that
context was visible in Eric's followup. It might have been nice if
Eric had written "C99 5.1.2.3", but it was perfectly clear to me what
he was citing. (As for C90 vs. C99, the section number happens to be
the same in both, and I don't think there were any relevant changes.)

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 5 '07 #37

P: n/a
On Thu, 29 Nov 2007 08:45:06 -0500, Eric Sosman
<es*****@ieee-dot-org.invalidwrote:
<snip Lisp example>
There's a wide family of languages that imitate a formula
notation (C,FORTRAN, Algol, Pascal, ...), but examples of
"non-formulaic" languages are not hard to find. Lisp is one,
assemblers usually focus on the operations rather than on
Assemblers generally write separately each instruction making up the
program being, er, written, but at least since very early days most
allow within instruction operands expressions which are evaluable at
translation time, i.e. 'constant' expressions in C terminology. E.g.

LOAD R1, BUFBASE + 3*SIZE_OF_ELEMENT + LEN_PART1
formulas, what little I saw of COBOL looked like formulas
transliterated into pidgin English, and somewhere in the high
COBOL has both the formula way and the nearly-English way.
Some perhaps many of its users and supporters emphasise the latter as
a unique advantage; the 'unique' part is unarguable.
holy Himalayas of ratiocination you'll find the monasteries
wherein dwell the lamas who can actually read APL.
APL does use infix and prefix operator syntax but NOT precedence and
associativity rules like all other formula langauges I know; except
for parens it 'binds' strictly right to left.
Let's not poke too much fun at Lisp, by the way. It's
challenging to read (although one gets better with practice),
but there are *no* rules of precedence or associativity (or
their formal-grammar counterparts) to confuse newbies, the
"operator overloading" diatribes never erupt, and indeed it's
trivial to introduce brand-new "operators" at need. That's
a lot of power; the obfuscation may be a worthwhile price.
(Nearly-consistent) postfix like FORTH (already mentioned) and
PostScript is similarly simple at the syntax level. (Without thereby
limiting semantics, as already noted at least once.)

- formerly david.thompson1 || achar(64) || worldnet.att.net
Dec 10 '07 #38

P: n/a
David Thompson wrote:
On Thu, 29 Nov 2007 13:43:33 +0000, Philip Potter <pg*@doc.ic.ac.uk>
wrote:
>In the context of replacing operators with functions, it's not the same
thing at all. Firstly, it requires you to replace x++ with increment(&x)
rather than increment(x) - so at best you can replace an operator with a
function call and another operator. Secondly, even increment(&x) doesn't
work everywhere x++ does: [snip: register storageclass is c.v.]
Having said that, I'm not sure if you can initialize a reference type
with a register lvalue in C++. <snip>

You can, but also &reg is fine in C++, not a c.v. as in C.
(I take it c.v. means "Constraint Violation?")

I did not know that. The mind boggles at the number of subtle
differences between C and C++.
Dec 10 '07 #39

P: n/a
On Mon, 10 Dec 2007 12:49:42 +0000, Philip Potter <pg*@doc.ic.ac.uk>
wrote:
David Thompson wrote:
On Thu, 29 Nov 2007 13:43:33 +0000, Philip Potter <pg*@doc.ic.ac.uk>
wrote:
In the context of replacing operators with functions, it's not the same
thing at all. Firstly, it requires you to replace x++ with increment(&x)
rather than increment(x) - so at best you can replace an operator with a
function call and another operator. Secondly, even increment(&x) doesn't
work everywhere x++ does: [snip: register storageclass is c.v.]
Having said that, I'm not sure if you can initialize a reference type
with a register lvalue in C++. <snip>
You can, but also &reg is fine in C++, not a c.v. as in C.

(I take it c.v. means "Constraint Violation?")
Yes. I probably should have capitalized it, as the usual practice here
is UB or occasionally U.B. for Undefined Behavior.
I did not know that. The mind boggles at the number of subtle
differences between C and C++.
Yep. See C++98 Annex C, and I'm not sure even that was entirely
complete -- and of course it doesn't consider the changes created by
C99 (though that did remove the differences for doubleslash comments,
and implicit int and implicit function declaration) and what appear to
me to be fairly significant changes made or proposed in C++ since '98.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Dec 24 '07 #40

This discussion thread is closed

Replies have been disabled for this discussion.