看起来GCC有一些优化认为来自不同翻译单元的两个指针永远不会相同,即使它们实际上是相同的.
码:
main.c中
#include <stdint.h>
#include <stdio.h>
int a __attribute__((section("test")));
extern int b;
void check(int cond) { puts(cond ? "TRUE" : "FALSE"); }
int main() {
int * p = &a + 1;
check(
(p == &b)
==
((uintptr_t)p == (uintptr_t)&b)
);
check(p == &b);
check((uintptr_t)p == (uintptr_t)&b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
公元前
int b __attribute__((section("test")));
Run Code Online (Sandbox Code Playgroud)
如果我用-O0编译它,它会打印出来
TRUE
TRUE
TRUE
Run Code Online (Sandbox Code Playgroud)
但是用-O1
FALSE
FALSE
TRUE
Run Code Online (Sandbox Code Playgroud)
所以p并且&b实际上是相同的值,但是编译器优化了它们的比较,假设它们永远不会相等.
我无法弄清楚,哪种优化做到了这一点.
它看起来不像严格的别名,因为指针是一种类型,而-fstrict-aliasing选项不会产生这种效果.
这是记录在案的行为吗?或者这是一个错误?
我打开了一个文件,在指针的地址找到了流ptr.我试图查看文件是否为空.使用以下内容
if (fgetc(ptr) != EOF)
Run Code Online (Sandbox Code Playgroud)
按预期工作.当文件为空时,不执行该语句.当文件不为空时,不执行该语句.
但是,使用
if (!feof(ptr))
Run Code Online (Sandbox Code Playgroud)
总是执行声明.
为什么会这样?有没有办法使用这个feof功能?
我知道在比较char指针和一些char值时你需要在指针前加上*,但我在一些代码中找到了一个比较:
char* c;
// ...
while (*c != ']' && *c != '\0') // search for some character
{
c++;
}
if (c == '\0')
{
return -1; // error
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:这是一个错误还是一个特例?不应该if (*c == '\0')有吗?
我在使用矢量迭代器时遇到了麻烦.我在一些地方读过,检查null迭代器是不可能的,检查迭代器的常用方法是在搜索后检查vector.end().例如:
vector< Animal* > animalList;
vector<Animal*>::iterator findInList(const type_info& type)
{
// Loop through list of Animals, if Dog found, return iterator to it
}
auto it = findInList(typeid(Dog));
// With a pointer I can check if it's null, but with an iterator I have to check against animalList.end();
Run Code Online (Sandbox Code Playgroud)
问题是容器可能是空的.使用迭代器,我不能返回null以指示容器为空或搜索失败.我可以返回vector :: end(),但cplusplus.com说:
If the container is empty, vector::end() function returns the same as vector::begin()
Run Code Online (Sandbox Code Playgroud)
然后对于vector :: begin()它说:
If the container is empty, the returned iterator value shall not be dereferenced.
Run Code Online (Sandbox Code Playgroud)
所以,如果我有一个空容器,vector …
Go Newbie问题:我正在尝试使用默认值初始化以下结构.我知道如果"Uri"是一个字符串而不是指向字符串的指针(*string),它会起作用.但我需要这个指针来比较结构的两个实例,如果没有设置Uri将是nil,例如当我从json文件解组内容时.但是,如何将这样的结构正确地初始化为"静态默认"?
type Config struct {
Uri *string
}
func init() {
var config = Config{ Uri: "my:default" }
}
Run Code Online (Sandbox Code Playgroud)
上面的代码失败了
cannot use "string" (type string) as type *string in field value
Run Code Online (Sandbox Code Playgroud) 我有兴趣为在Haskell中实现命令式语言的项目使用更有效的指针.已有一个库:Struct.有一篇博客文章和简要文档.
问题是链接树只有一个非常复杂的例子.对于像我这样每天不使用Haskell的人来说,与文档代码,模板haskell等进行战斗是相当费力的.
我需要一个简单的例子来开始,沿着表达这两种数据类型的方式:
import Data.IORef
data DLL a = DLL a (Maybe (IORef (DLL a))) (Maybe (IORef (DLL a)))
data DLLINT = DLLINT Int (Maybe (IORef DLLINT)) (Maybe (IORef DLLINT))
Run Code Online (Sandbox Code Playgroud)
对于熟练使用Haskell/GHC的人来说,这应该只是一些简单的界限.
如何使用Struct库表达上述数据类型之一?
在阅读了很多关于此的帖子后,我想澄清下一点:
A* a = new A();
A* b = a;
delete a;
A* c = a; //illegal - I know it (in c++ 11)
A* d = b; //I suppose it's legal, is it true?
Run Code Online (Sandbox Code Playgroud)
所以问题是关于使用已删除指针的副本的值.
我读过,在c ++ 11中读取a导致未定义行为的价值 - 但是读取它的价值b呢?
尝试读取指针的值(注意:这与解除引用它不同)会导致自C++ 14以来的实现定义行为,其中可能包括生成运行时错误.(在C++ 11中它是未定义的行为) 删除后指针本身会发生什么?
这编译和工作:
diff := projected.Minus(c.Origin)
dir := diff.Normalize()
Run Code Online (Sandbox Code Playgroud)
这不会(产生标题中的错误):
dir := projected.Minus(c.Origin).Normalize()
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解为什么吗?(学习Go)
以下是这些方法:
// Minus subtracts another vector from this one
func (a *Vector3) Minus(b Vector3) Vector3 {
return Vector3{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
}
// Normalize makes the vector of length 1
func (a *Vector3) Normalize() Vector3 {
d := a.Length()
return Vector3{a.X / d, a.Y / d, a.Z / d}
}
Run Code Online (Sandbox Code Playgroud) 假设我们在C或C++中定义了两个结构(我在C和C++中得到相同的结果,我认为规则是相同的,告诉我它们是否不相同).
一个值不完整的值成员:
struct abc{
int data;
struct nonexsitnow next; //error: field ‘next’ has incomplete type, makes sense since "struct nonexsitnow" hasn't been declared or defined.
};
Run Code Online (Sandbox Code Playgroud)
以及一个不完整类型的指针成员:
struct abc{
int data;
struct nonexsitnow *next; //pass?!
};
Run Code Online (Sandbox Code Playgroud)
为什么第二个定义不会导致任何问题?它使用struct nonexsitnow尚未创建!
我在下面的答案和评论中总结了这张表,希望它们对于详细说明是正确和有用的.
正如@ArneVogel提到,无论是struct Foo p;和struct Foo *p;是一个隐含的声明Foo,并struct Foo;明确地做这件工作(感谢@约翰布林).这对c来说几乎没有任何意义,但对c ++和行为有所不同:
In a situation where struct Foo is:
_______________________________________________________
| | undeclared | declared but | defined |
| | …Run Code Online (Sandbox Code Playgroud) 假设你有一组指针(是的......):
std::set<SomeType*> myTypeContainer;
Run Code Online (Sandbox Code Playgroud)
然后假设您要从SomeType的const方法搜索此集合:
bool SomeType::IsContainered() const
{
return myTypeContainer.find(this) != myTypeContainer.end();
}
Run Code Online (Sandbox Code Playgroud)
这不起作用.方法中的thisptr是一个const SomeType *const,我不能把它放进去find.问题是find需要一个const-ref,在这种情况下,这意味着传递的指针被视为const,但不是它指向的东西.
有没有办法顺利解决这个问题(不改变设置的模板类型)?