C标准规定:
指向结构对象的指针(适当地强制转换)指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.
如果所讨论的结构的第一个成员是匿名结构/联合,是否有任何可能的(和明确定义的)方法在C11中执行这样的"合适的强制转换"?或者,如果包含结构是匿名的,则执行"反之亦然"向后转换?
我想,使用与匿名结构相同的成员序列转换为非匿名结构将使得它不能很好地定义,因为它们不兼容,因此,不能保证具有相同的内存布局.
但是,C标准规定:
此外,如果它们的标记和成员满足以下要求,则在单独的转换单元中声明的两个结构,联合或枚举类型是兼容的:如果使用标记声明一个,则另一个应使用相同的标记声明.如果两者都在各自的翻译单元内的任何地方完成,则以下附加要求适用:其成员之间应存在一对一的对应关系<...>
我们可以尝试将此规则应用于匿名结构吗?比如说,如果我们有以下设置:
header.h:
struct container {
struct {
int a;
char b;
};
};
void print(struct container *pcontainer);
Run Code Online (Sandbox Code Playgroud)
sep.c:
#include <stdio.h>
#include "header.h"
void print(struct container *pcontainer){
printf("%d\n", ((struct { int a; char b; }*)pcontainer)->a);
}
Run Code Online (Sandbox Code Playgroud)
main.c中:
#include "header.h"
int main(void){
struct container container, *pcontainer;
pcontainer = &container;
pcontainer->a = 1;
print(pcontainer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(这在gcc(GCC)4.8.3 20140911上编译,输出1).
考虑在内的铸造中使用的匿名结构print功能和所述匿名结构是的第一构件struct container ,在卷起main.c.它们可以被视为"在单独的翻译单元中声明的类型"吗?此外,他们真的满足所有其他兼容性要求,还是我误解了什么?
这真让我抓狂。我正在 Visual Studio 2012 上编译我的项目。我想REG_BINARY使用RegOpenKeyEx和RegQueryValueEx调用读取注册表项。在调试(多线程调试)模式下,一切正常。但是,在发布(多线程)模式下,RegQueryValueEx会经常失败并显示错误代码ERROR_MORE_DATA。这是我正在使用的代码:
HKEY keyHandle;
TCHAR lpData[1024];
DWORD lpcbData;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &keyHandle) != ERROR_SUCCESS){
MessageBox(NULL, L"fail", L"title", MB_OK);
return NULL;
} else if (RegQueryValueEx(keyHandle, L"DigitalProductId", NULL, NULL, (LPBYTE)lpData, &lpcbData) != ERROR_SUCCESS){
MessageBox(NULL, L"fail!", L"title", MB_OK);
return NULL;
}
MessageBox(NULL, L"success", L"title", MB_OK);
Run Code Online (Sandbox Code Playgroud) 在MSVC和gcc(GCC)4.8.3 20140911上,以下编译和运行正常:
#include <stdio.h>
int func(int a, int b){
return 0;
}
int main(void){
int (*funcPointer)(int a, int b);
funcPointer = func;
printf("funcPointer = %p\n", funcPointer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这样的行为是定义明确的,还是非标准的,并且函数指针类型具有命名参数(即名称及其参数列表中的类型)实际上是非法的?
在C#中,自动实现的属性非常方便.但是,尽管它们除了封装它们的支持字段之外什么都不做,但它们仍然不能作为ref或out参数传递.例如:
public int[] arr { get; private set; } /* Our auto-implemented property */
/* ... */
public void method(int N) { /* A non-static method, can write to this.arr */
System.Array.Resize<int>(ref this.arr, N); /* Doesn't work! */
}
Run Code Online (Sandbox Code Playgroud)
在这个特定的情况下,我们可以解决这个问题:
public void method(int N) { /* A non-static method, can write to this.arr */
int[] temp = this.arr;
System.Array.Resize<int>(ref temp, N);
this.arr = temp;
}
Run Code Online (Sandbox Code Playgroud)
有没有更优雅的方法来使用C#中自动实现属性的支持字段的引用?
在阅读了这个问题之后:长度为前缀的字符串克服的零终止字符串有什么问题?我开始想知道,究竟是什么阻止了C实现为堆栈或堆上分配的任何char或wchar_t数组分配一些额外的字节,并使用它们作为"字符串前缀"来存储N其元素的数量?
然后,如果N-th字符是'\0',则N - 1表示字符串长度.
我相信这可以极大地提升诸如strlen或等功能的性能strcat.
如果程序广泛使用非0终结char数组,这可能会转向额外的内存消耗,但这可以通过编译器标志打开或关闭'\0'编译代码的常规"计数直到达到"例程来解决.
这种实施有哪些障碍?C标准是否允许这样做?这项技术会导致我没有考虑到哪些问题?
并且......实际上有没有这样做过?
c compiler-construction c-strings null-terminated compiler-optimization
我对C#中"默认构造函数"的含义感到非常困惑.很多人,包括我的编程教授,只是调用任何无参数构造函数"默认构造函数"(就像这里或这里的问题和答案一样).即使是default-constructor上的SO标签wiki 也说它是"无参数构造函数......经常(注意它经常说,而不是总是)由编译器生成".
如果要遵循此逻辑,构造函数是否为"默认"依赖于您可以如何调用它.即如果您可以将其称为"默认"方式,没有任何参数,则它是默认构造函数.
但是,MSDN,如果我正确地读它,似乎只将名称"default constructor"赋予无参数构造函数,该构造函数在没有指定其他构造函数时隐式生成,调用无参数基类构造函数,并且(与任何其他构造函数一样)将class字段初始化为其值.
考虑一下,这比"default" == "parameterless"以下更有意义:当您没有选择任何其他内容时,隐式生成的构造函数有点像默认选项.
那么,调用所有无参数构造函数的默认构造函数是否正确?
或者是它正确调用明确定义形式的构造函数public C(): base() {}(普通班)和protected C(): base() {}(抽象类)默认的构造函数,因为它们适合在MSDN默认构造函数的说明?
或者该术语是否仅适用于隐式生成的构造函数?
另外(可能是最重要的问题):这是该术语最广泛接受的定义,是正确还是不正确?
出于某种原因,我没有找到关于此的文档.看起来,在C#中,类的const字段在静态字段之前被初始化,因为从这段代码可以看出:
class Program {
static int p = f;
const int f = 10;
static void Main(string[] args){
System.Console.WriteLine("{0}", p);
System.Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
(这个输出10,而如果我更换const用static时,其输出0).
问题是:这种行为总是如此吗?另外,通常,不同类型的静态类字段的初始化顺序是什么?
我有以下用例:我正在构建一个自定义AST.作为我在AST上进行的某些操作的优化,我已经为AST节点定义了一个子列表,因此:
data NodeChHolder a = NNode [a] -- For "normal" operators
| ACNode (MultiSet a) -- For operators that can be re-ordered and parenthesized arbitrarily
| NCNode -- Empty, no children
Run Code Online (Sandbox Code Playgroud)
现在,我想让这个类型成为Functor.但是,有一个问题,因为MultiSet需要它的类型参数Ord.所以,这不起作用:
instance Functor NodeChHolder where
fmap f (NNode l) = NNode $ map f l
fmap f (ACNode s) = ACNode $ MultiSet.map f s
fmap _ NCNode = NCNode
Run Code Online (Sandbox Code Playgroud)
我得到一个错误,说"使用MultiSet.map"没有"Ord b的实例",这是公平的.
为解决此问题,我尝试使用ScopedTypeVariablesghc扩展的以下方法.我认为这类似于它如何与类型一起工作,但似乎类型类不同:
instance Functor NodeChHolder where
fmap f (NNode l) = NNode …Run Code Online (Sandbox Code Playgroud)