标签: pointers

为什么编译器会假设这些看似相等的指针不同?

看起来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选项不会产生这种效果.

这是记录在案的行为吗?或者这是一个错误?

c gcc pointers compiler-optimization language-lawyer

12
推荐指数
2
解决办法
824
查看次数

混淆== EOF vs feof

我打开了一个文件,在指针的地址找到了流ptr.我试图查看文件是否为空.使用以下内容

if (fgetc(ptr) != EOF)
Run Code Online (Sandbox Code Playgroud)

按预期工作.当文件为空时,不执行该语句.当文件不为空时,不执行该语句.

但是,使用

if (!feof(ptr))
Run Code Online (Sandbox Code Playgroud)

总是执行声明.

为什么会这样?有没有办法使用这个feof功能?

c pointers file feof fgetc

12
推荐指数
3
解决办法
6086
查看次数

将指针与字符串的char结尾进行比较

我知道在比较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')有吗?

c c++ pointers

12
推荐指数
2
解决办法
1828
查看次数

我可以针对null检查C++迭代器吗?

我在使用矢量迭代器时遇到了麻烦.我在一些地方读过,检查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 …

c++ pointers iterator vector nullptr

12
推荐指数
1
解决办法
2万
查看次数

初始化struct中的字符串指针

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)

struct pointers go

12
推荐指数
1
解决办法
2万
查看次数

使用Struct库的快速不连续指针(静态,拆箱等)

我有兴趣为在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库表达上述数据类型之一?

haskell pointers imperative-programming ghc

12
推荐指数
1
解决办法
155
查看次数

删除后在c ++中的指针

在阅读了很多关于此的帖子后,我想澄清下一点:

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中它是未定义的行为) 删除后指针本身会发生什么?

c++ pointers c++11 c++14

12
推荐指数
2
解决办法
1484
查看次数

"不能取地址"和"不能调用指针方法"

这编译和工作:

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)

methods struct pointers go

12
推荐指数
2
解决办法
9724
查看次数

C/C++结构不完整的成员类型不一致?

假设我们在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;明确地做这件工作(感谢@约翰布林).这对几乎没有任何意义,但对和行为有所不同:

               In a situation where struct Foo is:
_______________________________________________________
|               | undeclared | declared but | defined |
|               | …
Run Code Online (Sandbox Code Playgroud)

c c++ struct pointers

12
推荐指数
3
解决办法
1675
查看次数

无法将'const pointer const'传递给const ref

假设你有一组指针(是的......):

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,但不是它指向的东西.

有没有办法顺利解决这个问题(不改变设置的模板类型)?

c++ templates pointers const pass-by-const-reference

12
推荐指数
2
解决办法
1081
查看次数