Can't get my C programs to compile if I use math.h

I didn’t say that this statement never makes sense.

What I said was, that in this case it doesn’t make sense because argc isn’t changed anywhere.
So this just results in an endless loop if argc>1. If that’s indeed what you’re intending you should explicitely state it:

if (argc > 1)
  while (1) {
...
}

You’re saving an unneeded comparison for every loop invocation that way… :wink:

Hi wolfi323,

OK I resign.

But you agree with me that a command like

argv = 1

will produce nothing but bad crashes, in general, if the variable argv (as usual) is defined by

char  **argv;

like in code of the OP,
while

while (argc > 1) {

whith argc being defined by

int  argc;

can make sense in some situations, don’t you? :wink:

Best wishes
Mike

Yes.
That’s why I pointed to this error in post #11 already:

while

while (argc > 1) {

whith argc being defined by

int  argc;

can make sense in some situations, don’t you? :wink:

Please read my last post again. I only ever said it does not make sense in the case of the OP’s code.
But yes, that condition itself is ok.

I said that I would resign.

Hi ballsystemlord (the OP),

back to your 1st post (post #1 in this thread): you reported the error message

In
/usr/include/bits/mathcalls.h
that - using gcc / glibc - is included by /usr/include/math.h
you’ll find the prototypes (or definitions) for default math functions like sin, cos, and even exp, …
that are part of the C language as described by Kernighan & Ritchie (even ANSI version of their book),
but you don’t find no prototype (or definition) for the function exp2l.
That function should probably calculate 2^x as a long double.

To me it seems that the code that you have is bad in even other aspects
like assigning an arbitrary value of 1 to the pointer variable

char  **argv

as in the code listing that you included in post #16 of this thread
and that is discussed in the above postings by wolfi323 (and others).

However, although I’m quite familiar with C, I’m not familiar with gcc / glibc.

Did you see
exp2l - GNU Gnulib

Anyway, perhaps your `worm.c’ proves to be a real worm in the end ……:expressionless:

Good luck
Mike

Yes, but you also asked if I would agree with you. :wink:

Yes, it returns 2^x as long double.
As I also pointed out already some time ago, run this in a terminal window to get informations about exp2l:

man exp2l

You can do the same with other C standard library functions as well, of course.

I looked through math.h (here /usr/include/math.h) as I did on other systems before,
thereafter /usr/include/bits/mathcalls.h, because I can read C, I thought.

Am I blind?

OK.

Read through /usr/include/math.h again.

It’s really cryptic.
That’s not the way that C was meant to be.
I admit - that I once as well thought that, writing `advanced’ code (i.e. code using all and more features of a programming language)
would help to improve the world, or would help to prove myself.
I’m 50 years old now, and I’m sorry to say that I learned my lesson the hard way (having weeks wasted searching for bugs),
that just this isn’t true.

With respect to especially this math.h:
A few function prototypes more, in the simple style, would probably even be more efficient with respect to overall compile time (!),
compared to the sophisticated and specialized C macro definitions currently present in math.h of the glibc.

The important things in life are simple.

It as well is simple to say that this, in principle, is the wrong forum for such comments,
as openSUSE makes use of gcc/glibc - and is there any choice ? - and that the devs of
openSUSE aren’t responsible for that.

But on the basis of this ‘math.h’ - who dares to judge whether all functions therein are declared in the proper way
without having studied that file for several weeks?

Reading man pages, and beleiving that they tell the truth, is one thing (although they should be correct!).
Understand a header file of that sophisticated kind is another.

OK, that can not be that way!
I’m completely wrong and numb!!
You think?
Have a look at
/usr/include/stdio.h !
That still is readable code !!

Wish all of you the best
Mike

Well, the include files are meant to be read by the compiler. For humans there are the man pages.
That “cryptic” stuff sometimes is easier and more efficient to read and analyze for a machine… :wink:

Also, because calling functions has some overhead, for some compiler built-in (“inlined”) versions are used which makes the include files harder to be read by humans.
And those include files are there to be used on a variety of different systems, not just openSUSE Linux. That also doesn’t make them more simple…

So just stick to the documentation (that’s what it’s there for!) and do believe it tells the truth. (If not it’s a bug)
And don’t try to be too clever… Accept that this has been written by people who have more knowledge about that than you (and me). :wink:

On 2013-09-23, wolfi323 <wolfi323@no-mx.forums.opensuse.org> wrote:
> And don’t try to be too clever… Accept that this has been written by
> people who have more knowledge about that than you (and me). :wink:

It depends. Unfortunately the performance of libm leaves a lot to be desired; I’d argue that the underlying reason is
the authors were trying to be too clever. And don’t confuse being knowledgeable with being clever. Knowledge is much
easier to acquire than the ability to be clever, making the latter much more valuable.

Hi wolfi323,

OK I made a mistake, because I was tired.
/usr/include/math.h
wasn’t the only cryptic code.
/usr/include/bits/mathcalls.h
added to this.

The motivation behind the code in mathcalls.h is quite obvious:
Try to avoid similar declarations for exp2(), exp2l(), exp2f, … etc., but do it once and for all.

However, my point remains, that this might not be helpful, if the resulting code gets too sophisticated.

I wrote header files myself, because I had to, in order to produce maintainable code.

As a C programmer, foreign header files for me usually are a source to see what’s in stock,
and what isn’t.

In the given case we finally may be talking about the difference between the repeated (and thus boring?) declarations of


double exp2(double);
long double exp2l(long double);
float exp2f(float);
etc.

which is simple,
compared to code in math.h like


#define _Mdouble_        double
#define __MATH_PRECNAME(name,r)    __CONCAT(name,r)
#define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_STD
#define _Mdouble_END_NAMESPACE   __END_NAMESPACE_STD
#include <bits/mathcalls.h>
#undef    _Mdouble_
#undef _Mdouble_BEGIN_NAMESPACE
#undef _Mdouble_END_NAMESPACE
#undef    __MATH_PRECNAME

...

# ifndef _Mfloat_
#  define _Mfloat_        float
# endif
# define _Mdouble_        _Mfloat_
# define __MATH_PRECNAME(name,r) name##f##r
# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
# define _Mdouble_END_NAMESPACE   __END_NAMESPACE_C99
# include <bits/mathcalls.h>
# undef    _Mdouble_
# undef _Mdouble_BEGIN_NAMESPACE
# undef _Mdouble_END_NAMESPACEwolfi323,
# undef    __MATH_PRECNAME

...

#  ifndef _Mlong_double_
#   define _Mlong_double_    long double
#  endif
#  define _Mdouble_        _Mlong_double_
#  define __MATH_PRECNAME(name,r) name##l##r
#  define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
#  define _Mdouble_END_NAMESPACE   __END_NAMESPACE_C99
#  define __MATH_DECLARE_LDOUBLE   1
#  include <bits/mathcalls.h>
#  undef _Mdouble_
#  undef _Mdouble_BEGIN_NAMESPACE
#  undef _Mdouble_END_NAMESPACE
#  undef __MATH_PRECNAME

...
etc. etc.

Yes, OK, a float, a double, and a long double, etc., may be something different on different machines,
and provisions have to be made for that in a header file for math functions.

And further, there may be inline code to be defined as a macro to speed up things.

But there really is no use in making code that complicated.

In order to make a really crude comparison:
just compare the lines of code required for each of the two versions - i.e. the ‘numb’ explicit declaration of functions
using types ‘double’, ‘float’, ‘long double’ etc., vs. macro definitions as in the 2nd example above !

wolfi323,
you’re friendly, and I acknowledge that.

But as a C programmer, at the end of the day, I would still like to be able to understand the header files (as well as the code) that I make use of.

Therefore:

No, that’s not my stance, and it shouldn’t be yours either :wink:

Another aspect of this: on the basis of beleiving the documentation, how could you ever be able to find serious bugs in the tools that you use,
or to judge whether some source code may implement some worm or virus (I mean the source code basis, not binary executables).

Look, coding an elastic-plastic Finite Element program using MPW under MacOS8 on PowerPC processors, I had the impression
(or made the experience) that the PowerPC processors (up to G3 at least) obviously produced wrong results - at least occasionally -
whenever fused multiply-add was used, because the convergence of the algorithm then broke down by an order of magnitude.

Even believe in correct calculations of your main processor ?
As much as in foreign code, like header files ?

I didn’t work with gcc yet.
So I still miss the routine experience that things (usually) work fine.
Perhaps that’s my current fault.

Still I prefer to understand what I do - or better what code I make use of.

Best wishes
Mike

On 2013-09-23, ratzi <ratzi@no-mx.forums.opensuse.org> wrote:
> As a C programmer, foreign header files for me usually are a source to
> see what’s in stock, and what isn’t.

You’re too conscientious. For mathematical functions I wouldn’t bother with the header files. I’d just gcc -S code.c and
look at the obfuscated assembler output (with -masm=intel if you’re sane). Sadly in C/C++, mathematical libraries are
designed to be flexible/universal at cost of being poor performers in precisely the way LAPACK/BLAS are not. If you want
anything mathematically done properly in C/C++ especially on arrays, then you’re up to no good unless you’re using a
linear algebra/inline assembler library. I recommend writing your own or using Adner Fog’s. Now Adner Fog is clever!

Hi flymail,

You’re right, looking for the assembler code that’s generated has always been a good idea (already 25 years ago …).
Especially if one tries to optimize certain pieces of a program, or if one just wants to see what’s going on.
Most things on the other hand can well be coded in plain C - this language already is quite close to assembler code.

There always is the possibility to translate FORTRAN code to C using f2c.
In principle there is only one element of the FORTRAN language that can not truely be implemented in C,
which is the computed goto - the C statement switch' is a poor replacement in this case, because the latter still relies on a comparison for each case:', which is very different.
But the computed goto of FORTRAN, on the other hand, in practice is used quite scarcely.

Other things like call by reference, that are common in FORTRAN, can well be implemented in C just as well.

No, I don’t subscribe to that.
Yes, C++ seems to be a different thing here.
But, using plain C, I was well able to write fast BLAS routines.
To achieve that, I didn’t need to code in assembler, nor in FORTRAN (i.e. the language in which LAPACK is coded).

Best wishes
Mike

On 2013-09-24, ratzi <ratzi@no-mx.forums.opensuse.org> wrote:
> In principle there is only one element of the FORTRAN language that can
> not truely be implemented in C,
> which is the computed goto - the C statement

I don’t understand. Although I never use it, C does have a goto statement (e.g. see
http://www.programiz.com/c-programming/c-goto-statement ).

>> then you’re up to no good unless you’re using a linear algebra/inline
>> assembler library.
> But, using plain C, I was well able to write fast BLAS routines.

You do know what the LA in `BLAS’ means don’t you? :wink:

Target label in C is static. FORTRAN has ability to dynamically select target of GOTO statement at run time from a list.

On 2013-09-25, arvidjaar <arvidjaar@no-mx.forums.opensuse.org> wrote:
> Target label in C is static. FORTRAN has ability to dynamically select
> target of GOTO statement at run time from a list.

Ahh how torrid! Reminds me a BASIC program I once saw that had the line: GOTO RAND!

In which case, surely the best C equivalent isn’t a switch-case branch pattern, but through the use of an array of
function pointers?

On 2013-09-25 14:31, flymail wrote:
> On 2013-09-25, arvidjaar <arvidjaar@no-mx.forums.opensuse.org> wrote:
>> Target label in C is static. FORTRAN has ability to dynamically select
>> target of GOTO statement at run time from a list.
>
> Ahh how torrid! Reminds me a BASIC program I once saw that had the line: GOTO RAND!
>
> In which case, surely the best C equivalent isn’t a switch-case branch pattern, but through the use of an array of
> function pointers?
>

I used that trick in assembler, and it was nice and readable.

An array of chars for the selector on a menu, and an array of
destinations for a goto or a gosub.


Cheers / Saludos,

Carlos E. R.
(from 12.3 x86_64 “Dartmouth” at Telcontar)

On 2013-09-26, Carlos E. R. <robin_listas@no-mx.forums.opensuse.org> wrote:
> An array of chars for the selector on a menu, and an array of
> destinations for a goto or a gosub.

I thought gosub was from BASIC!

As for goto, I think using it in C/C++ is terrible form. I’ve seen it in some coded directly translated from FORTRAN,
but the code inevitably could be rearranged to be much more efficient and readable manner by judicious choice of a
conditional loop (i.e. for, while, or do) with an occasional break. Rearrangement is more efficient because while
unconditional jumps incur little overhead, correct selection of conditional jumps inevitably reduces the number of
jumps. As for readability, let’s just say there’s no `goto’ equivalent in Python and with good reason; however, there’s
also no switch…case and I think that’s restrictive.

flymail wrote:
> On 2013-09-26, Carlos E. R. <robin_listas@no-mx.forums.opensuse.org>
> wrote:
>> An array of chars for the selector on a menu, and an array of
>> destinations for a goto or a gosub.

> As for
> readability, let’s just say there’s no `goto’ equivalent in Python
> and with good reason; however, there’s also no switch…case and I
> think that’s restrictive.

Hah, what a cissy language :slight_smile: Perl has goto, in fact it has three types
of goto (there’s always more than one way to do it)

http://perldoc.perl.org/functions/goto.html

Just look at all the gnarly qualifications in the description. Anything
FORTRAN can do, Perl can do better. What a great language!

On 2013-09-26, Dave Howorth <djh-novell@no-mx.forums.opensuse.org> wrote:
> Just look at all the gnarly qualifications in the description. Anything
> FORTRAN can do, Perl can do better. What a great language!

With some rephrasing, I’d entirely agree :slight_smile:

Just look at all the gnarly qualifications in the description. Anything Perl can do, FORTRAN can do even worse. What terrible languages!

I’m still undecided on which language has the more awful syntax; I think I’m leaning towards Perl :).