Autor Thema: "assignment makes pointer from integer without a cast"  (Gelesen 9476 mal)

impi226

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
Hallo zusammen!

Gespannt habe ich heute das Einsteiger-Tutorial hier verfolgt. Leider bin ich dann beim Auslagern der Ausgabe-Funktion und der Clearscreen-Funktion irgendwie hängen geblieben.

Hier mein Quelltext:

#include "main.h"

void main(void)
{
    clear_screen();
    print_line("Hallo Welt!");
}

void clear_screen()
{
    int x;
    int y;

    for (x = 0; x < 80; x++)
        for (y = 0; y < 80; y++)
draw_character(' ', 7, 0, x, y);
}

void print_line(char string[])
{
    int i;

    for (i = 0; string[i] != '\0'; i++) {
        draw_character(string[i], 7, 0, i, 0);
    }
}

void draw_character(char c, char forecolour, char backcolour, int x, int y)
{
    unsigned short attrib = (backcolour << 4) | (forecolour & 0x0F);
    volatile unsigned short *where;
    where = 0xB8000 + (y * 80 + x);
    *where = c | (attrib << 8);
}

Die Fehlermeldung ist:

~/c-projects/dj-kernel$ make
gcc -m32 -ffreestanding -Wall -g -fno-stack-protector -nostdinc -c -o main.o main.c
main.c: In function ‘draw_character’:
main.c:32: warning: assignment makes pointer from integer without a cast
ld -melf_i386 -Ttext=0x100000 -o kernel boot.o main.o

Eine Antwort wäre sehr nett! :-)

Gute Nacht,
Daniel

P.S.: Achja und der komplette Screen ist Lila beim Ausführen... ;-)
« Letzte Änderung: 28. April 2011, 01:45 von impi226 »

DesL

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 28. April 2011, 02:15 »
    volatile unsigned short *where;
    where = 0xB8000 + (y * 80 + x);
Da where ja ein unsigned short Pointer ist, und du versuchst ihm einen Wert zu zuweisen, meckert GCC.
Caste den Wert rechts einfach zu einem unsigned short*

impi226

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. April 2011, 09:55 »
Also du meinst:

where = 0xB8000 + (unsigned short *)(y * 80 + x);
Fehler ist zwar weg, aber Ausgabe ist immernoch Müll. ;-)

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 28. April 2011, 10:19 »
Hallo,


eher so:where = (unsigned short *)(0xB8000 + (y * 80 + x));0xB8000 ist für den Compiler auch nur eine Zahl und kein Pointer.

Das Deine Ausgabe aber nur "Müll" ist muss IMHO eine andere Ursache haben (die obige Zeile sollte eigentlich auch ohne den Cast funktionieren, nur eben nicht ohne Warnung).

War so ein Zeichen nicht eigentlich 2 Byte groß im VGA-Puffer?


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

DesL

  • Beiträge: 23
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. April 2011, 11:52 »
ein Byte fürs Zeichen, ein Byte für die Farbe

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #5 am: 28. April 2011, 12:18 »
Moin,

was mir gerade aufgefallen ist: in clear_screen() geht deine y-for-schleife auch bis 80, es gibt aber nur 25 Zeilen

Für deinen lila-Bildschirm hab ich gerade auch keine Lösung, sorry.

Grüße,
LittleFox

impi226

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 28. April 2011, 12:24 »
Moin,

was mir gerade aufgefallen ist: in clear_screen() geht deine y-for-schleife auch bis 80, es gibt aber nur 25 Zeilen

Für deinen lila-Bildschirm hab ich gerade auch keine Lösung, sorry.

Grüße,
LittleFox

oh ja, stimmt, weiß auch nicht, was mich da gestern nacht geritten hat. bin in dem bereich aber auch noch newbie, aber es reizt mich halt auch diesen bereich mal ein bisschen auszuprobieren... ;-)

impi226

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 28. April 2011, 12:25 »
Also du meinst:

where = 0xB8000 + (unsigned short *)(y * 80 + x);
Fehler ist zwar weg, aber Ausgabe ist immernoch Müll. ;-)

hatte ich auch ausprobiert. aber vielleicht liegt es auch an meiner clear_screen-schleife. ich werde gleich mal weiterprobieren... ;-)

danke auf jeden fall!

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #8 am: 28. April 2011, 12:27 »
Versuch mal aus
unsigned short attrib = (backcolour << 4) | (forecolour & 0x0F);
ein
unsigned char attrib = (backcolour << 4) | (forecolour & 0x0F);

ein short sind ja 16Bit (2 Byte) und das Attributbyte ist, wie der name schon sagt, 1 byte groß


EDIT: totaler unsinn, dann geht das Bitschieben nicht ... am besten ignorieren ;)

EDIT 2: vielleicht *where = c | (char)(attrib << 8);
« Letzte Änderung: 28. April 2011, 12:31 von littlefox »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 28. April 2011, 12:33 »
where = (unsigned short *)(0xB8000 + (y * 80 + x));
Ich schlage vor:
where = ((unsigned short*) 0xb8000) + (y * 80 + x);Man muss ja zwei Bytes weiter für jedes Zeichen, nicht nur eins.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

impi226

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 28. April 2011, 12:51 »
where = (unsigned short *)(0xB8000 + (y * 80 + x));
Ich schlage vor:
where = ((unsigned short*) 0xb8000) + (y * 80 + x);Man muss ja zwei Bytes weiter für jedes Zeichen, nicht nur eins.

juhuu, danke für den tipp. hat funktioniert. muss mich unbedingt nochmal mehr mit pointern und type (casting) beschäftigen, komme sonst beruflich aus der php-ecke, der schlampensprache! :-D

danke!

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 28. April 2011, 13:55 »
Hallo,


Ich schlage vor:where = ((unsigned short*) 0xb8000) + (y * 80 + x);Man muss ja zwei Bytes weiter für jedes Zeichen, nicht nur eins.
Hm, da sehe ich aber nicht wo das mit den 2 Bytes vor passieren soll.
Ich hätte eher an sowas gedacht :where = (unsigned short*)( 0xB8000 + ((y * 80 + x)*2) );Oder werden Offsets bei der Pointer-Arithmetik (nicht bei Array-Zugriffen o.ä.) immer mit der Element-Größe multipliziert?


Grüße
Erik (der gerade an seinen C-Kenntnissen zweifelt :cry: )
Reality is that which, when you stop believing in it, doesn't go away.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #12 am: 28. April 2011, 14:03 »
Moin,

es sind short's, keine char's

Grüße,
LittleFox

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 28. April 2011, 14:39 »
Oder werden Offsets bei der Pointer-Arithmetik (nicht bei Array-Zugriffen o.ä.) immer mit der Element-Größe multipliziert?
Ja. Lern C. :-P

Und Arrayzugriffe sind doch genau dasselbe. foo[x] ist das gleiche wie *(foo + x) und *(x + foo) und x[foo].
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #14 am: 28. April 2011, 15:05 »
x[foo]? echt?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 28. April 2011, 15:53 »
Hallo,


Und Arrayzugriffe sind doch genau dasselbe. foo[x] ist das gleiche wie *(foo + x) und *(x + foo) und x[foo].
Dann frage ich mich wie man überhaupt unausgerichtete Pointer erzeugen kann.
Für  int* foo = (int*)0xB8000;  int x = 5;  ergibt  foo[ x]  was anderes als  foo + x. Muss ja eigentlich auch weil wie sonst sollen unausgerichtete Pointer erzeugt werden? Und bei x[foo] bin ich mir nicht ganz sicher was raus kommt aber da x eben kein Pointer ist dürfte der C-Compiler da nicht einfach so irgend eine Element-Größe annehmen können also bleibt das effektiv bei char. Bei einer normalen Addition wird doch der Ergebnistyp auch fest von einem der Operatoren abgeleitet und nicht aus einer Prioritätsentscheidung gebildet.

Ich hab jetzt auf die schnelle keinen C-Compiler zur Hand, Bitte probiere das doch mal kurz aus.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #16 am: 28. April 2011, 15:58 »
Falls du mich mit ausprobieren meinst, ich hab auch kein Compiler zur Hand (nur C#), bin auf Arbeit.

Aber x[Foo] könnte, wenn man x castet, wirklich sinn ergeben:

Foo = 0xB8000
X = 0x10

Foo[X] = 0xB8010 (Foo + X)

X[Foo] = 0xB8010 (X + Foo)

...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 28. April 2011, 16:24 »
Du glaubst mir nicht, dass ich C kann, erik? ;)

#include <stdint.h>
#include <stdio.h>

int main(void)
{
    int* x = (int*) 0xb8000;

    printf("%p\n", &x[5]);
    printf("%p\n", &*(x + 5));
    printf("%p\n", &5[x]);
    printf("%p\n", &*(5 + x));
    printf("%p\n", &*(int*)((uintptr_t) x + 5));

    return 0;
}

Ausgabe:
0xb8014
0xb8014
0xb8014
0xb8014
0xb8005
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 28. April 2011, 20:39 »
Hallo,


Du glaubst mir nicht, dass ich C kann, erik? ;)
Das hab ich nicht geschrieben (und auch nicht gedacht).

Von dem Ergebnis bin ich aber doch ziemlich entsetzt. Vor allen das Ausgabe 2 und 4 das selbe Ergebnis liefern verstehe ich nicht. Den Ergebnistyp einer Addition muss der Compiler doch aus den beteiligten Operanden ableiten und da hätte ich nicht vermutet das der Compiler da eine Art Prioritätsentscheidung über beide Operanden macht, ich hätte mit "der Typ des linken Operand wird für das Ergebnis genommen" gerechnet.
Warum liefert Ausgabe 5 ein anderes Ergebnis? uintptr_t ist doch auch ein Pointer für ein 4 Byte großes Element oder etwa nicht?

Das ist auf jeden Fall ein Grund mehr warum ich VHDL so mag, VHDL ist wenigstens recht konsequent und verlässlich in seinem Verhalten. Da könnte man nie zwei unterschiedliche Datentypen einfach so mit einander Addieren.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

SHyx0rmZ

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 28. April 2011, 21:28 »
Bei Ausgabe 2 nimmt er doch den Typen von x? Gerade deswegen entspricht es ja Ausgabe 1. Und uintptr_t ist nunmal kein Pointer, sondern ein Integer.
@X="krJhbuaesrytre c a cnR.ohut";while@X[/(..)(.)/];@X=@X[3..-1]+$1;print$2;end
"Scheiß auf Perl, wir haben Kekse" - Emperor Ruby

 

Einloggen