默认情况下可以序列化原语'void',为什么对象'Void'不能扩展Serializable?
添加示例:
RootImplementation将有一个编译错误,说"Void不在其范围内",因为它没有扩展Serializable.虽然将'someMethod'声明为'void',但这不是问题.
public interface Root<R extends Serializable> extends Serializable {
R someMethod();
}
public class RootImplementation implements Root<Void> {
public Void someMethod() {
return null;
}
}
Run Code Online (Sandbox Code Playgroud) 当我有时间的时候,我一直在教自己C几个月,我遇到了一个问题我不知道如何解决.
具体来说,当我尝试使用gcc编译它时,我得到:
geometry.c:8: error: conflicting types for ‘trapezoid’ geometry.c:7: note: previous declaration of ‘trapezoid’ was here geometry.c:48: error: conflicting types for ‘trapezoid’ geometry.c:7: note: previous declaration of ‘trapezoid’ was here geometry.c:119: error: conflicting types for ‘trapezoid_area’ geometry.c:59: note: previous implicit declaration of ‘trapezoid_area’ was here geometry.c: In function ‘cone_volume’: geometry.c:128: error: called object ‘3.14100000000000001421085471520200371742248535156e+0’ is not a function geometry.c: In function ‘cylinder_volume’: geometry.c:136: error: called object ‘3.14100000000000001421085471520200371742248535156e+0’ is not a function
现在,我想我可能需要对这些功能进行类型转换,但同样,我不确定.
看起来它想要读取我定义为3.141的PI作为函数.有没有办法可以避免使用魔法数字3.141(虽然它比其他数字少得多)?
//Geometric formulae
#include <stdio.h>
#include <math.h>
#define …Run Code Online (Sandbox Code Playgroud) 例如,如果我创建变量:
void helloWorld;
Run Code Online (Sandbox Code Playgroud)
我该怎么办?因为它什么都不代表,起初我认为没有什么可以用它做的.我知道函数使用void没有返回值,但变量有用吗?
- 编辑 -
我找到了答案.我现在知道在Java,C++和C等编程语言中,void变量是非法的.感谢您的所有答案!
我正在使用F#,Visual Studio单元测试框架(又名MSTest)和FluentAssertions为我的F#库编写单元测试.
测试方法应该具有void或Task的返回类型.在C#中这很容易:
[TestMethod]
public void TestMethod1()
{
false.Should().BeFalse();
}
Run Code Online (Sandbox Code Playgroud)
在F#我有以下内容:
[<TestMethod>]
member this.TestMethod1() =
false.Should().BeFalse(null)
|> ignore
Run Code Online (Sandbox Code Playgroud)
否则返回类型更改为,FluentAssertions.PrimitivesBooleanAssertions因此Test Runner看不到它.
如何避免|> ignore每次测试结束?
f# unit-testing void vs-unit-testing-framework fluent-assertions
在任意类型上执行SFINAE时,通常需要将表达式的结果转换为void.我已经看到了两种方法; 演员无效:
(void)(expr) // or static_cast<void>(expr)
Run Code Online (Sandbox Code Playgroud)
或者,使用带有void prvalue RHS的逗号运算符:
(expr), void()
Run Code Online (Sandbox Code Playgroud)
我的理解是,在两种情况下都要expr评估(对于良好的形式,在非评估的上下文中)和结果(或结果类型,在非评估的上下文中)被丢弃; 在任何一种情况下,即使是病理类也不可能T覆盖T::operator void()或operator,(T, void).(参见:为什么是"运营商无效"不投语法调用?,什么的'无效()'中的'自动F(PARAMS) - > decltype(...,无效())'呢?).
也就是说,这两个成语是等价的,还是在某种情况下,一个人应该优先于另一个(可能是非标准的编译器)?如果没有,是否有任何理由(例如可理解性)偏好一个而不是另一个?
目前我正在使用传统的c ++代码库.在此代码库中,指向对象的指针将转换为void-pointers,然后存储在c-library中.请考虑以下代码:
class interface {
public:
virtual void foo() {
std::cout << "Interface" << std::endl;}
virtual ~interface(){};
};
class debug_interface: public interface {
public:
virtual void foo() {
std::cout << "Debug Interface" << std::endl;}
};
Run Code Online (Sandbox Code Playgroud)
对象interface并debug_interface在堆上分配,地址存储在void指针中.在某些时候,指针被检索,然后再转换回基类interface.然后调用虚函数调用.看到
int main(int argc, char *argv[]){
void *handle = reinterpret_cast<void*>(new interface());
void *debug_handle = reinterpret_cast<void*>(new debug_interface());
//void *handle = new interface();
//void *debug_handle = new debug_interface();
interface *foo1 = reinterpret_cast<interface*>(handle);
interface *foo2 = reinterpret_cast<interface*>(debug_handle);
//interface *foo1 = static_cast<interface*>(handle);
//interface …Run Code Online (Sandbox Code Playgroud) 为什么以下代码无法编译?即使这样做也是合法的void* ptr = 0;
template <void* ptr = 0>
void func();
int main() {
func();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我问,因为我发现一个非常值得信赖的来源做了类似的事情,但无法在我的机器上编译
注意应该已经发布了编译器错误以及我的问题,所以在这里
so_test.cpp:1:23: error: null non-type template argument must be cast to template parameter type 'void *'
template <void* ptr = 0>
^
static_cast<void *>( )
so_test.cpp:1:17: note: template parameter is declared here
template <void* ptr = 0>
^
so_test.cpp:5:5: error: no matching function for call to 'func'
func();
^~~~
so_test.cpp:2:6: note: candidate template ignored: substitution failure [with ptr = …Run Code Online (Sandbox Code Playgroud) 在我的回答中,我提到解除引用void指针是一个坏主意.但是,当我这样做时会发生什么?
#include <stdlib.h>
int main (void) {
void* c = malloc(4);
*c;
&c[0];
}
Run Code Online (Sandbox Code Playgroud)
汇编:
gcc prog.c -Wall -Wextra
prog.c: In function 'main':
prog.c:4:2: warning: dereferencing 'void *' pointer
*c;
^~
prog.c:5:4: warning: dereferencing 'void *' pointer
&c[0];
^
prog.c:5:2: warning: statement with no effect [-Wunused-value]
&c[0];
^
Run Code Online (Sandbox Code Playgroud)
这是来自Wandbox的图片,对于那些说它没有发生的人:
和Live demoIdeone中的一个.
它实际上会尝试读取c指向的内存,然后获取该结果,但实际上什么都不做?或者这条线根本没有效果(但GCC不会产生警告).
我在想,既然编译器对数据类型一无所知,在不知道类型大小的情况下,它将无法做很多事情.
为什么derefencing a void*不会产生错误,只是警告?
如果我尝试作业,我会收到错误:
无效使用void表达式
但不应该单独解除引用会产生错误吗?
我注意到GCC触发器:
warning: dereferencing ‘void *’ pointer
Run Code Online (Sandbox Code Playgroud)
在获取解除引用的void表达式的地址时:
int main()
{
void *p = "abcdefgh";
printf("%p\n", p);
printf("%p\n", &*p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,表达式p相当于&*p根据C标准:
§6.5.3.2地址和间接运营商
一元&运算符返回其操作数的地址.如果操作数具有类型''type'',则结果具有类型''指向类型''的指针.如果操作数是一元*运算符的结果,则不会对该运算符和&运算符进行求值,结果就好像两者都被省略,除了对运算符的约束仍然适用且结果不是左值.
知道Clang不会触发此警告也很重要.
免责声明
为了更好的解释,请考虑这个:
int main()
{
int *p = NULL;
printf("%p\n", (void *) p);
printf("%p\n", (void *) &*p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码与Clang和GCC完美编译并运行.C标准清楚void指针,你可以取消引用它们(从而得到一个void值)但你不能使用表达式的结果.