更新 - 许多人坚持要我为该物业申报iVar.有些人说不是这样,因为我正在使用Modern Runtime(64位).我可以确认我已经成功使用@property而没有iVars几个月了.因此,我认为'正确'的答案是解释为什么在64位上我突然必须明确声明iVar何时(并且仅当)我将从子类访问它.到目前为止,我见过的唯一一个可能是GCC错误(感谢Yuji).毕竟不是那么简单......为了澄清可能的错误:当从基类继承时,子进程无法访问父进程的iVar,并且在访问iVar之前,该子进程也恰好使用@synthesize实现了一个UNRELATED访问器.
我一直在摸不着头几个小时 - 我没有太多使用遗产.
在这里,我设置了一个简单的Test B类,它继承自Test A,其中声明了一个ivar.但是我得到了变量未声明的编译错误.这只发生在我添加属性和合成声明时 - 没有它们就可以正常工作.
TestA标题:
#import <Cocoa/Cocoa.h>
@interface TestA : NSObject {
NSString *testString;
}
@end
Run Code Online (Sandbox Code Playgroud)
TestA实现为空:
#import "TestA.h"
@implementation TestA
@end
Run Code Online (Sandbox Code Playgroud)
TestB标题:
#import <Cocoa/Cocoa.h>
#import "TestA.h"
@interface TestB : TestA {
}
@property (nonatomic, retain) NSString *testProp;
@end
Run Code Online (Sandbox Code Playgroud)
TestB实现(错误 - 'testString'未声明)
#import "TestB.h"
@implementation TestB
@synthesize testProp;
- (void)testing{
NSLog(@"test ivar is %@", testString);
}
@end
Run Code Online (Sandbox Code Playgroud) gcc信息文件在x86-64特定标志的部分中说明,其中包括:
There is no `-march=generic' option because `-march'
indicates the instruction set the compiler can use, and there
is no generic instruction set applicable to all processors.
In contrast, `-mtune' indicates the processor (or, in this
case, collection of processors) for which the code is
optimized.
Run Code Online (Sandbox Code Playgroud)
我的问题是,当没有给出-march选项时,gcc编译的指令(子)集是什么?在webosphere中有很多关于-march和-mtune的相关信息,但我找不到哪个能回答这个简单的问题.它不能是march = native,否则就不可能编译通用分发内核和二进制包.
/usr/bin/make -f nbproject/Makefile-Debug.mk SUBPROJECTS= .build-conf
/usr/bin/make -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/cppapplication_1
mkdir -p build/Debug/GNU-MacOSX
rm -f build/Debug/GNU-MacOSX/main.o.d
g++ -arch i386 -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.cpp
cc1plus: error: unrecognized command line option "-arch"
make[2]: *** [build/Debug/GNU-MacOSX/main.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 311ms)
simpatico$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin10/4.5.1/lto-wrapper
Target: x86_64-apple-darwin10
Configured with: ../gcc-4.5.1/configure --prefix=/opt/local --build=x86_64-apple-darwin10 --enable-languages=c,c++,objc,obj-c++,fortran,java --libdir=/opt/local/lib/gcc45 --includedir=/opt/local/include/gcc45 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.5 --with-local-prefix=/opt/local --with-system-zlib …Run Code Online (Sandbox Code Playgroud) 不,这不是如何检测整数溢出的重复?.问题是一样的,但问题是不同的.
gcc编译器可以优化掉溢出检查(使用-O2),例如:
int a, b;
b = abs(a); // will overflow if a = 0x80000000
if (b < 0) printf("overflow"); // optimized away
Run Code Online (Sandbox Code Playgroud)
gcc人认为这不是一个错误.根据C标准,溢出是未定义的行为,它允许编译器执行任何操作.显然,任何事情都包括假设溢出永远不会发生.不幸的是,这允许编译器优化掉溢出检查.
最近的CERT文件中描述了检查溢出的安全方法.本文建议在添加两个整数之前执行类似的操作:
if ( ((si1^si2) | (((si1^(~(si1^si2) & INT_MIN)) + si2)^si2)) >= 0) {
/* handle error condition */
} else {
sum = si1 + si2;
}
Run Code Online (Sandbox Code Playgroud)
显然,当你想确保结果有效时,你必须在一系列计算中的每个+, - ,*,/和其他操作之前做这样的事情.例如,如果要确保数组索引不受限制.这太麻烦了,几乎没有人这样做.至少我从未见过一个系统地执行此操作的C/C++程序.
现在,这是一个根本问题:
在访问阵列之前检查数组索引很有用,但不可靠.
使用CERT方法检查一系列计算中的每个操作都是可靠但无用的.
结论:在C/C++中没有有用且可靠的方法来检查溢出!
我拒绝相信这是在编写标准时的意图.
我知道有一些命令行选项可以解决问题,但这并没有改变我们对标准或其当前解释存在根本问题的事实.
现在我的问题是:gcc的人服用的"未定义行为"的解释时,它允许他们优化掉溢出检查,否则过犹不及是C/C++标准坏了吗?
补充说明: 对不起,您可能误解了我的问题.我不是问如何解决这个问题 - 这已经在其他地方得到了回答.我在问一个关于C标准的更基本的问题.如果没有有用且可靠的检查溢出的方法,那么语言本身就是可疑的.例如,如果我使用边界检查创建一个安全的数组类,那么我应该是安全的,但是如果边界检查可以被优化掉,我就不会这样做.
如果标准允许这样做,则标准需要修订或标准需求修订的解释.
补充说明2: 这里的人似乎不愿意讨论"未定义行为"的可疑概念.C99标准列出了191种不同的未定义行为( …
我正在尝试使用gcc 4.7构建qtCreator 2.3并且我收到以下错误:
错误:无法找到字符串文字运算符""
我正在使用mingw32-make -ltoqtCreator源目录.有什么想法吗?
我有以下C++代码,它给了我一个惊喜.问题是如果我抛出一些东西,除了在catch块内重新抛出,程序将通过调用abort终止并在GCC4中给出错误消息,"在抛出'int'实例后调用终止".如果我只是用"扔"; 重新扔进catch区,一切都会好的.
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;
int main()
{
try{
throw std::string("first throw");
}
catch(std::string &x){
try{
std::cout << x << std::endl;
// throw; // if I use this line, all is fine.
throw int(2); // but if I use this line, it causes Abort() to be called
}
catch (int &k){
throw;
}
catch(...)
{
cout << "all handled here!"<< endl;
}
}
catch(...){
std::cout<< "never printed" << endl;
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个用gcc 3.4.3编译的静态库.我想在现在用gcc-4编译的代码中使用它.我含糊地读到gcc-3和gcc-4二进制文件不兼容,并且需要重新编译库,但只是想对此进行确认.不管怎样,gcc-3库可以和gcc-4一起使用吗?
它是GCC 4.7.0还是我?我做错了什么?
这会引发std::system_error "不允许操作"的异常:
struct DumbFib {
size_t operator()(size_t n) { return fib(n); }
static size_t fib(size_t n) {
return n<2 ? 1 : fib(n-2)+fib(n-1);
}
};
void sample() {
DumbFib dumbfib;
thread th{ dumbfib, 35 }; // <- system_error!
th.join();
};
Run Code Online (Sandbox Code Playgroud)
虽然这有效:
void work(size_t loop) {
for(int l = loop; l>0; --l) {
for(int i = 1000*1000; i>0; --i)
;
cerr << l << "...";
}
cerr << endl;
}
int main() {
//sample();
thread t …Run Code Online (Sandbox Code Playgroud) float myArray[myArraySize] = {1};
Run Code Online (Sandbox Code Playgroud)
在上面的表达式中,只有第一个元素是init和1.如何使用复合文字(不是memset)初始化所有带元素的元素?
我在unix上使用GCC 4.2进行编译.
我有一个C程序,其中包含一些尚未使用的静态函数.我想禁用这些特定功能的警告.我不想禁用所有-Wunused-function警告.我正在使用GCC 4.6.特别:
ek@Apok:~/source$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)
我遵循文档中的建议(使用push和pop),但我无法使其工作.
我已经创建了一些简化的源代码来调查问题.我正在编译它们gcc -Wall -o pragma pragma.c(在哪里pragma.c).我的第一个版本pragma.c看起来像这样:
void foo(int i) { }
static void bar() { }
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
正如所料,我在编译时得到了这个:
pragma.c:3:13: warning: ‘bar’ defined but …Run Code Online (Sandbox Code Playgroud)