GURU NEEDED : macro SQUARE(x) for any type x

B

bolega

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval}) // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

this macro is given in several posts like

http://groups.google.com/group/comp...5da6/e5fe657622e5595b?q="typedef+xtype"&pli=1

there is a problem with typedef

Bolega
 
L

luser- -droog

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})  // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

this macro is given in several posts like

http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/38ef2...

there is a problem with typedef

Bolega

What problem?
 
R

Rivka Miller

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})  // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

this macro is given in several posts like

http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/38ef2...

there is a problem with typedef

Bolega

try if this works

#define square(x) ({typeof(x) temp=x; temp*temp;})

Rivka
 
L

luser- -droog

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})  // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

this macro is given in several posts like

http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/38ef2...

there is a problem with typedef

Bolega

OIK

#define SQR(x) pow((x),2)
or
#define SQR(x) exp(2 * log(x))
 
H

Hans Vlems

OIK

#define SQR(x) pow((x),2)
or
#define SQR(x) exp(2 * log(x))- Tekst uit oorspronkelijk bericht niet weergeven -

- Tekst uit oorspronkelijk bericht weergeven -

What happens for x=0 in the second example?
 
G

Gert-Jan de Vos

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})  // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

this macro is given in several posts like

http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/38ef2...

there is a problem with typedef

Bolega

Why not just an inline function template (this being c.l.c++)?

template <typename T>
inline T square(T value)
{
return value*value;
}

Gert-Jan
 
L

luser- -droog

What happens for x=0 in the second example?

Rats! And you can't do a ternary 'cause you'd have to
mention x twice.

But that would be a penalty in lisp, too wouldn't it?
An expression with a side-effect would perform the
side-effect twice, right?
 
B

Bart van Ingen Schenau

Basically, I have spent a few hours experimenting and searching on the
comp.lang.c/c++

Let me use SQR for brevity and saving line

Here are progressively refined macros :

#define SQR(x) ((x)*(x))

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})  // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

The ({ ... }) construct is not valid in standard C or standard C++. It
is a GCC extension.
If you want a standard-conforming macro that works for any type and
also yields a value of that same type, you are stuck with the first
macro you present.
There is no way to write such a macro in standard C without evaluating
x twice.

In C++, you have the option of using an inline templated function, as
shown by Gert-Jan de Vos.

If your portability needs do not extend beyond GCC (and compilers
accepting the same dialect), you can use an expression-block similar
to the second block, as shown by Rivka Miller.

Bart v Ingen Schenau
 
J

James Kuyper

Why not just an inline function template (this being c.l.c++)?

template<typename T>
inline T square(T value)
{
return value*value;
}

Because this is also cross-posted to c.l.c. That could mean he's one of
those people who thinks C and C++ are a single language called C/C++,
but alternatively, it could mean that he needs a separate solution for
each language, or a single solution that works in both languages.
 
S

Stefan Monnier

Because this is also cross-posted to c.l.c. That could mean he's one of
those people who thinks C and C++ are a single language called C/C++, but
alternatively, it could mean that he needs a separate solution for each
language, or a single solution that works in both languages.

Since he also cross-posted to g.e.help, I guess we should presume he
thinks Help is also a language in the same family or that he also wants
a solution in that language?


Stefan
 
J

James Kuyper

Since he also cross-posted to g.e.help, I guess we should presume he
thinks Help is also a language in the same family or that he also wants
a solution in that language?

I have not the slightest idea why he cross-posted to g.e.help. The
speculation I wrote about his motives for posting to c.l.c and c.l.c++
reflects my past experiences with other people who made similar
cross-postings.
 
P

PKM

#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval}) // NOTE,
closure or {} inside () is a valid idea in C, and thus no return is
needed.

I don't see how this could possibly work:

/*test.c*/
#define SQR(x) ({typedef xtype=x; xtype xval=x; xval*xval})

int main(void)
{
SQR(2);
return 0;
}

$ gcc test.c
test.c: In function ‘main’:
test.c:7: error: typedef ‘xtype’ is initialized (use __typeof__
instead)
test.c:7: error: expected ‘;’ before ‘}’ token

Recompiling after making those changes yields

test.c: In function ‘main’:
test.c:7: error: expected ‘(’ before ‘xtype’
test.c:7: error: ‘xtype’ undeclared (first use in this function)
test.c:7: error: (Each undeclared identifier is reported only once
test.c:7: error: for each function it appears in.)
test.c:7: error: expected ‘;’ before ‘xval’
test.c:7: error: ‘xval’ undeclared (first use in this function)

And even if it did compile, isn't it the case that
this code is attempting to use the same token as both
a value and as a type?
 
K

Keith Thompson

PKM said:
I don't see how this could possibly work:

It can't.

It depends on two gcc-specific extensions, and it gets both of them
wrong.

Here's a version that actually works with gcc:

#define SQR(x) ({typedef typeof(x) xtype; xtype xval=(x); xval * xval;})

The "typeof" keyword is non-standard, as is the use of a "statement
expression".

There is no general solution in standard C that avoids evaluating the
argument twice.

But in practice, this:

#define SQR(x) ((x) * (x))

works perfectly well. The convention of using all-caps for macro names
warns the user that the argument might be evaluated more than once.
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top