Forum: Compiler & IDEs Nutzung von pow10


von Moritz A. (moritz_a)


Lesenswert?

Ich wollte mir eigentlich gerade ein paar Zehnerpotenzen in einer 
Lookup-Table speichern, da das generische pow() zu viel Platz braucht, 
bekam beim kompilieren aber den Fehler:
1
main.h:36:24: warning: built-in function ‘pow10’ declared as non-function [enabled by default]
2
 const uint16_t __flash pow10[] = {

Dachte ich mir nun also 'schön, bringt die Toolchain wohl schon mit.' 
Aber doch nicht so ganz:
1
main.c:229:85: error: called object ‘pow10’ is not a function or function pointer
2
         […] -= pow10(menuepos-1);

Die Suche nach einem Header o.ä. zu dieser Funktion brachte mich auch 
nicht wirlich weiter:
1
> ack-grep pow10 /usr/lib/gcc/ /usr/lib/avr
2
/usr/lib/gcc/avr/4.8.1/plugin/include/builtins.def
3
388:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
4
389:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
5
390:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)

Hat jemand einen Tipp zur Verwendung für mich?

Danke.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?


von Moritz A. (moritz_a)


Lesenswert?

Danke, aber hilft mir so auch erstmal nicht weiter:
1
> cat main.c
2
#define _GNU_SOURCE 
3
#include <math.h>
4
5
int main (void) {
6
    double foo = 2;
7
    double bar;
8
    bar = pow10(foo);
9
}
10
> avr-gcc -c -mmcu=attiny461 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -Wall -Wextra -Wpedantic -Wstrict-prototypes -Wa,-adhlns=./main.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/main.o.d main.c -o main.o 
11
main.c: In function ‘main’:
12
main.c:7:5: warning: implicit declaration of function ‘pow10’ [-Wimplicit-function-declaration]
13
     bar = pow10(foo);
14
     ^
15
main.c:7:11: warning: incompatible implicit declaration of built-in function ‘pow10’ [enabled by default]
16
     bar = pow10(foo);
17
           ^
18
main.c:6:12: warning: variable ‘bar’ set but not used [-Wunused-but-set-variable]
19
     double bar;
20
            ^

von MBr (Gast)


Lesenswert?

Hallo,

beim Linken die Option -lm verwenden.
Noch eine Andere Frage muss der Dateityp double sein?

von Moritz A. (moritz_a)


Lesenswert?

Aus
Johann L. schrieb:
> http://linux.die.net/man/3/pow10

habe ich das »double pow10(double x);« gezogen.

MBr schrieb:
> beim Linken die Option -lm verwenden.

Bringt weiterhin den selben Fehler :/

von Karl H. (kbuchegg)


Lesenswert?

> paar Zehnerpotenzen in einer Lookup-Table speichern

Welche?

Die Frage ist nämlich auch, ob du dir für die kleinen 10-er Potenzen 
überhaupt den Luxus eines double antun willst.

> ... avr-gcc -c -mmcu=attiny461 ....
Sicher, dass du überhaupt Floating Point haben willst?
Oder reicht dir nicht einfach nur eine Tabelle, die aus den Werten 1, 
10, 100, 1000, 10000 als uint16_t besteht?
Dann nenn die Funktion ganz einfach nicht pow10, wenn dieser Name 
(unzulässigerweise) schon vom gcc belegt ist, sondern irgendwie anders, 
und alles ist gut.


Wozu brauchst du das überhaupt?

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

> built-in function ‘pow10’

build-in heisst eingebaut, nenne deine Tabelle (die sowieso ein 
unzureichender Ersatz für pow10 wäre) p10 und greife per p10[x] darauf 
zu.

von Moritz A. (moritz_a)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> ... avr-gcc -c -mmcu=attiny461 ....
> Sicher, dass du überhaupt Floating Point haben willst?
> Oder reicht dir nicht einfach nur eine Tabelle, die aus den Werten 1,
> 10, 100, 1000, 10000 als uint16_t besteht?

Genau die habe ich auch:
1
const uint16_t __flash powten[] = {
2
    10000,
3
     1000,
4
      100,
5
       10,
6
        1
7
};
Dass sie "rückwärts" ist spart mit in dem Fall sogar eine Substraktion.

Mir ging es mehr um das generelle, falls ich das mal verwenden möchte, 
wie es dann tut – also Lernen für die Zukunft, nicht für den aktuelle 
Fall.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Moritz A. schrieb:
> main.c:7:5: warning: implicit declaration of function ‘pow10’
> [-Wimplicit-function-declaration]

Also ist pow10 nicht in math.h enthalten. Damit wird vom Compiler

der Funktionsprototyp int pow10(int) angenommen.

Und das wiederum erklärt den Folgefehler:

> main.c:7:11: warning: incompatible implicit declaration of built-in function 
‘pow10’ [enabled by default]


Dir fehlt der passende Prototyp.

Mal in den Headerdateien gestöbert, wo pow10 deklariert wird?

von Moritz A. (moritz_a)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Mal in den Headerdateien gestöbert, wo pow10 deklariert wird?

Genau das habe ich ja versucht, aber nix gefunden:

Moritz A. schrieb:
> Die Suche nach einem Header o.ä. zu dieser Funktion brachte mich auch
> nicht wirlich weiter:
1
> ack-grep pow10 /usr/lib/gcc/ /usr/lib/avr
2
/usr/lib/gcc/avr/4.8.1/plugin/include/builtins.def
3
388:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
4
389:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
5
390:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)

Rufus Τ. Firefly schrieb:
> der Funktionsprototyp int pow10(int) angenommen.

Ganz am Anfang war es auch int/int, nur nach dem Hinweis auf 
http://linux.die.net/man/3/pow10 hatte ich es auf double geändert. Der 
Fehler blieb der gleiche.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
> Mal in den Headerdateien gestöbert, wo pow10 deklariert wird?

pow10 ist eine GNU-Erweiterung:

http://linux.die.net/man/3/pow10

und offenbar nicht in der AVR-Libc enthalten.

von Rolf Magnus (Gast)


Lesenswert?

Johann L. schrieb:
> und offenbar nicht in der AVR-Libc enthalten.

Das ist wohl schon etwas länger bekannt:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=26994
(hab ich übrigens mit ca. 30 Sekunden Googeln gefunden...)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wenn man nicht will, daß GCC was spezielles mit pow10 veranstaltet, 
hülft -fno-builtin-pow10.

von Dr. Sommer (Gast)


Lesenswert?

Mit C++ kann man sich seine eigene "pow" -Funktion definieren die zur 
Compile-Zeit läuft und somit das Ergebnis in den Flash gepackt werden 
kann:
1
#include <iostream>
2
#include <cstdint>
3
4
template <typename T>
5
constexpr T staticPow (T a, unsigned long long b) {
6
        return b == 0 ? 1 : a * staticPow (a, static_cast<decltype (b)> (b-1));
7
}
8
9
constexpr uint16_t powten [] = {
10
        staticPow (10, 4), staticPow (10, 3), staticPow (10, 2), staticPow (10, 1) };
11
12
int main () {
13
        for (auto x : powten)
14
                std::cout << x << std::endl;
15
}

Das iostream und std::cout Zeug ist nur zur Demonstration. Das constexpr 
an der Array-Definition stellt sicher dass die Berechnung vom Compiler 
durchgeführt wird und nur das Ergebnis im Programm landet. Dank dem 
Template funktioniert das auch mit allen numerischen Typen wie integer, 
float etc.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.