该函数返回-1。
但是,(void*)
在以下代码中的含义是什么:
没有它可以工作吗?
test = shmat(shm_id, NULL, 0);
if (test == (void *)-1) {
/* handle shmat failure */
}
答案 0 :(得分:16)
shmat
有以下原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);
即。它返回一个指向void
的指针,而不是一个整数。
如果出错,它会将整数-1强制转换为指向void 的指针。从Linux联机帮助页shmat(2):
成功时,
shmat()
返回附加共享内存段的地址;如果出现错误,则会返回(void *) -1
,并设置errno
以指示错误原因。
这就是必须正确进行比较以检查错误返回的方式。 C11标准对6.5.9p5-6中的运算符==
说明如下:
5否则,至少有一个操作数是指针。如果一个操作数是指针而另一个是空指针常量,则空指针常量将转换为指针类型。
如果一个操作数是一个指针到一个对象类型而另一个是一个指针到一个合格或不合格的void版本,前者将被转换为类型后者。
6两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和开头的子对象)或函数,两者都是指向最后一个元素的指针相同的数组对象,或者一个指向一个数组对象末尾的指针,另一个是指向不同数组对象的开头的指针,该数组对象恰好跟随地址空间中的第一个数组对象.109)
也就是说,标准定义了2个转换的行为:一个操作数是指向void的指针,另一个操作数是指向其他操作数的指针;或者一个操作数是一个指针,另一个操作数是空指针常量(即0,或(void *)0,或者左右)。由于没有强制转换的-1
既不是空指针常量,也不是指针,标准不会为此类情况指定任何行为,因此行为未定义"by the omission of any explicit definition"。
test == -1
错了,test == (void *) -1
是对的(ish)。
事实证明这仍然是一个灰色区域。 -1
是int
,在我的计算机上,它是32位。实现定义了整数到指针的转换。 GCC manuals say:
如果指针表示大于整数类型,则指向整数的转换会丢弃最高有效位,如果指针表示小于整数类型,则符号扩展 [2],否则这些位没有变化。
用脚注2说
GCC的未来版本可以零扩展,或使用目标定义的ptr_extend模式。不要依赖签名扩展。
因此,这意味着(void *)-1
也可能变得不正确;更安全的方法是将其写为(void *)(intptr_t)-1
。
由于某种原因,(void *)0
(即空指针)不用于发出错误信号(即使在C中使用这样的指针在标准方面是错误的)。
答案 1 :(得分:2)
函数int
返回void*
,因此类型转换用于将-1(// Import the SQL Server JDBC Driver classes
import java.sql.*;
class Example
{
public static void main(String args[])
{
try
{
// Build the connection string, and get a connection
System.out.println("1.");
System.out.println("2.");
String connectionUrl = "jdbc:jtds:sqlserver://UK-SB-Server:53569;DatabaseName=helpdesk;user=helpdesk;password=MyPwd;Tds=8.0;PrepareSql=3;XaEmulation=false";
System.out.println("3.");
Connection con = DriverManager.getConnection(connectionUrl);
System.out.println("Connected.");
// Create and execute an SQL statement that returns some data.
String SQL = "SELECT * from dbo.AllowedValues";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
// Iterate through the data in the result set and display it.
while (rs.next())
{
System.out.println(rs.getString(1) + " " + rs.getString(2));
}
}
catch(Exception e)
{
System.out.println("Error - " + e.getMessage());
System.exit(0);
}
}
}
)转换为正确的类型(C:\Progra~1\Java\jdk1.6.0_45\bin\javac C:\JavaTest\example.java
)。
实际上,是的,它可以工作,但你会从编译器得到一些警告。
永远不要忽视他们可以隐藏错误的警告。