【问题标题】:error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive] in makefile错误:从“void*”转换为“int”在 makefile 中丢失精度 [-fpermissive]
【发布时间】:2014-10-18 19:16:06
【问题描述】:

在 ubuntu 12.04 LTS(64 位)上编译以下 makefile 时遇到此错误:

Ana.cxx:21:46: error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]

在这一行:

21 : TThread::Printf("Start of Ana %x \n" ,(int)ptr);

这是生成文件:

ObjSuf        = o
SrcSuf        = cxx
DllSuf        = so
ExeSuf        =
OutPutOpt     = -o 
CXXFLAGS      = -g -Wall -fPIC -DOSF1 
CXX           = g++
CCFLAGS       = -g -Wall -DOSF1 
CC            = gcc
LD            = g++
LDFLAGS       = -g
SOFLAGS       = -shared
ROOTCFLAGS   := $(shell root-config --cflags) -DFILL_ON_FLY 
ROOTLIBS     := $(shell root-config --libs) -lNew -lThread -lMinuit -lPhysics
ROOTGLIBS    := $(shell root-config --glibs)  -lNew -lThread
EVENTO        = BINAEvent.$(ObjSuf) Ana.$(ObjSuf) BINAEventDict.$(ObjSuf)     mwpc_software.o tcpip.o Genbood.o  
EVENTS        = BINAEvent.$(SrcSuf) Ana.$(SrcSuf) BINAEventDict.$(SrcSuf) mwpc_software.c tcpip.c Genbood.c 
EVENTLIB      = $(ROOTGLIBS)
EVENTEXE      = ana
OBJS          = $(EVENTO)
    .SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)
    .PHONY:    Aclock Hello Tetris
     $(EVENTEXE):     $(OBJS)
         $(LD) $^ $(ROOTLIBS) $(OutPutOpt) $@
         @echo "$@ done"
     clean:
         @rm -f $(OBJS) core *~ *Dic* ana *.o
     .SUFFIXES: .$(SrcSuf)
     BINAEvent.$(ObjSuf): BINAEvent.h
       BINAEventDict.$(SrcSuf): BINAEvent.h BINAEventLinkDef.h
       @echo "Generating dictionary $@..."
       @rootcint -f $@ -c $^
      .$(SrcSuf).$(ObjSuf):
       $(CXX) $(CXXFLAGS) $(ROOTCFLAGS) -c $<
    .c.$(ObjSuf):
     $(CXX) $(CXXFLAGS) $(ROOTCFLAGS) -c $<

投射这个的正确方法是什么?

提前致谢。

【问题讨论】:

  • 试试(unsigned int)ptr(unsigned long)ptr

标签: c++ c gcc casting makefile


【解决方案1】:

错误与makefile无关。错误在源代码中,在错误显示的行上。

在您的平台上,指针不适合 int。如果您将指针转换为整数,您可能应该使用stdint.h 中的intptr_tuintptr_t,它们保证足够大。

我不知道TThread::Printf 是什么,它不是标准的。但是使用printf 打印指针地址的常用方法是将指针作为void* 传递并使用%p 格式说明符。 TThread::Printf 也可能是这种情况。

【讨论】:

    【解决方案2】:

    int(32bit) 类型不够大,无法容纳 64 位指针 void*

    【讨论】:

      【解决方案3】:

      问题与你的Makefile无关;这是您的 C++ 源代码中的错误。幸运的是,您已经向我们展示了错误所在的行。

      在 C 中打印指针值的正确方法是使用 %p 说明符,它需要 void* 类型的参数:

      TThread::Printf("Start of Ana %p\n", (void*)ptr);
      

      ptr 显然已经属于 void* 类型,因此不需要强制转换,但其他指针类型需要它。

      这假设TThread::Printfprintf 一样工作;给定它当然应该的名称,但不能保证。

      对于 C++,我通常建议将 C++ I/O 与 &lt;&lt; 运算符一起使用(对于指针,您必须小心 char*,它有一个重载,将其视为指向字符串的指针),但是在这种情况下可能不可用。

      如果你真的想要,你可以将指针值转换为整数类型,但这不是一个好主意,如果你只是想打印它的值,当然也没有必要。在&lt;stdint.h&gt;&lt;cstdint&gt; 中定义的uintptr_tintptr_t 类型保证能够保存转换后的void* 指针值而不会丢失信息(如果没有符合条件的整数类型,则不会定义) . int 不是,将指针转换为int 很容易丢失信息。

      【讨论】:

        【解决方案4】:

        我的解决方案是使用“long long”而不是“int”

        【讨论】:

        • 这不是一个好主意。在long long 大于指针的常见实现中,它是次优的。在 long long 与指针一样大的实现中,它并不比 (u)intptr_t%p 的已发布答案更好。 (在 long long 小于指针的罕见实现中,您还没有修复错误,但如果您设法找到这样的实现,我会感到惊讶。)
        • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
        • @Mgetz 它确实提供了问题的答案。这是一个糟糕的答案,但它符合 SO 标准。
        猜你喜欢
        • 2014-10-19
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        相关资源
        最近更新 更多