Avatar billede krismort Nybegynder
14. juli 2005 - 12:03 Der er 14 kommentarer

typecast fra void* til long uden warning?

hej,
hvordan kan man typecaste fra en void* til en long uden at der MSVC giver en warning ?

- Kristian
Avatar billede arne_v Ekspert
14. juli 2005 - 18:39 #1
hvilken version af MSVC og præcis hvilken kode ?

(jeg kan ikke umiddelbart genskabe problemet - hvis det er et problem altså -
det er jo en lidt suspekt cast)
Avatar billede driis Nybegynder
14. juli 2005 - 23:19 #2
Jeg antager du vil udskrive adressen i memory på et-eller-andet. Hvis det ikke er formålet, er jeg enig med arne_v i at det cast lyder lidt suspekt.

I MSVC 7.1 (Visual Studio .NET) giver følgende:
int main()
{
    char p = 0;
    void * ptr = (void *)&p;
    long address = (long)ptr;
}
Følgende warning i default projektopsætning:
e:\Projects\cpptest\main.cpp(7) : warning C4311: 'type cast' : pointer truncation from 'void *' to 'long'

Det skyldes at Visual Studio per default slår flaget "Detect 64 bit portability issues" til per default ( /Wp64 ). Så brokker compileren sig over ting, der kan skabe problemer på en 64 bit maskine. Og nævnte cast kan netop skabe problemer , idet en long er 32 bit på begge platforme, mens pointere er 32 bit på en 32 bit platform, og 64 bit på en 64 bit platform.

Hvis din kode aldrig skal køres på en 64 bit maskine, kan du slå warningen fra ved i project settings -> C/C++ -> General - at sætte "Detect 64 bit portability issues" til "No". Med mindre det er et hobbyprojekt eller lignende vil jeg dog i stedet anbefale at caste til en 64 bit datatype - så skulle du være på den sikre side.
Avatar billede arne_v Ekspert
14. juli 2005 - 23:24 #3
hvis man bare vil udskrive adressen så er %p i en printf vel udmærket ...
Avatar billede driis Nybegynder
14. juli 2005 - 23:26 #4
Ja, det kan du have ret i. Men der kan selvfølgelig være andre grunde til at man ønsker at lave castet - selvom jeg ikke lige umiddelbart kan komme på hvilke ;-)
Avatar billede krismort Nybegynder
14. juli 2005 - 23:47 #5
Jeg skal fjerne warnings fra flg. stykke kode uden at slå den fra i compiler settings.
( det er ikke tilladt at slå warnings fra i vores projekt ).
kompileren vi bruger er MSVC 7.1

---------------- kode -------------------
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <string>

void showWin32Console() {
      static const WORD MAX_CONSOLE_LINES = 500;
      int hConHandle;
      long lStdHandle;
      CONSOLE_SCREEN_BUFFER_INFO coninfo;
      FILE *fp;
      // allocate a console for this app
      AllocConsole();
      // set the screen buffer to be big enough to let us scroll text
      GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
      coninfo.dwSize.Y = MAX_CONSOLE_LINES;
      SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
      coninfo.dwSize);
      // redirect unbuffered STDOUT to the console
      lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
      hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "w" );
      *stdout = *fp;
      setvbuf( stdout, NULL, _IONBF, 0 );
      // redirect unbuffered STDIN to the console
      lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
      hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "r" );
      *stdin = *fp;
      setvbuf( stdin, NULL, _IONBF, 0 );
      // redirect unbuffered STDERR to the console
      lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
      hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "w" );
      *stderr = *fp;
      setvbuf( stderr, NULL, _IONBF, 0 );
      // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
      // point to console as well
      ios::sync_with_stdio();
  }
----------------- kode --------------------
Avatar billede arne_v Ekspert
14. juli 2005 - 23:59 #6
int hConHandle;
      long lStdHandle;

burde vel være:

      HANDLE hConHandle;
      HANDLE lStdHandle;

?
Avatar billede arne_v Ekspert
15. juli 2005 - 00:01 #7
og hvis I ikke har handle fordi I ikke har installeret PSDK så:

      void *hConHandle;
      void *lStdHandle;
Avatar billede arne_v Ekspert
15. juli 2005 - 00:02 #8
jeg slog lige _open_osfhandle op - hConHandle skal godt nok være int - sorry
Avatar billede krismort Nybegynder
15. juli 2005 - 00:10 #9
hvis jeg laver hConHandle til HANDLE så støder jeg bare ind i endnu flere fejl
Avatar billede krismort Nybegynder
15. juli 2005 - 00:11 #10
ehm warnings :)
Avatar billede arne_v Ekspert
15. juli 2005 - 00:16 #11
og hvis du kun ændrer

long lStdHandle;

til

void *lStdHandle;

(og fjerner de cast til long) ?
Avatar billede krismort Nybegynder
15. juli 2005 - 00:24 #12
så opstår samme problem ved
hConHandle = _open_osfhandle( lStdHandle, _O_TEXT);

hvor _open_osfhandle er deklareret som _open_osfhandle(intptr_t, int)

intptr_t er :
typedef _W64 int            intptr_t;
Avatar billede krismort Nybegynder
15. juli 2005 - 00:26 #13
Jeg tror jeg har løst problemet ved at gøre således:

---------------- kode -----------------------
#include <string>
#include <windows.h>

#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
using namespace std;


void showWin32Console() {
      static const WORD MAX_CONSOLE_LINES = 500;
      int hConHandle;
      void* lStdHandle;
      CONSOLE_SCREEN_BUFFER_INFO coninfo;
      FILE *fp;
      // allocate a console for this app
      AllocConsole();
      // set the screen buffer to be big enough to let us scroll text
      GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
      coninfo.dwSize.Y = MAX_CONSOLE_LINES;
      SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
      coninfo.dwSize);
      // redirect unbuffered STDOUT to the console
      lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
           
      hConHandle = _open_osfhandle( (intptr_t)lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "w" );
      *stdout = *fp;
      setvbuf( stdout, NULL, _IONBF, 0 );
      // redirect unbuffered STDIN to the console
      lStdHandle = GetStdHandle(STD_INPUT_HANDLE);
      hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "r" );
      *stdin = *fp;
      setvbuf( stdin, NULL, _IONBF, 0 );
      // redirect unbuffered STDERR to the console
      lStdHandle = GetStdHandle(STD_ERROR_HANDLE);
      hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT);
      fp = _fdopen( hConHandle, "w" );
      *stderr = *fp;
      setvbuf( stderr, NULL, _IONBF, 0 );
      // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
      // point to console as well
      ios::sync_with_stdio();
  }
---------------------------------------------
Avatar billede krismort Nybegynder
15. juli 2005 - 00:27 #14
Jeg kan ikke umildbart se at der skulle komme nogen warnings der....
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester