对于像C++这样的语言,标准的存在是必须的.好的编译器会尽力(最好是大多数好的编译器)来遵守.许多编译器都有语言扩展,其中一些是标准允许的,其中一些不是.后两种例子:
gcc的类型
microsoft的编译器允许纯虚函数声明同时具有纯指定符(= 0)和定义(标准禁止 - 我们不讨论为什么,这是另一个主题:)
(还有很多其他的例子)
这两个示例在以下意义上都很有用:example1是一个非常有用的功能,它将在c ++ 0x中以不同的名称提供.example2也很有用,微软决定不尊重没有意义的禁令.
我很感激编译器提供语言扩展,帮助开发人员完成日常工作.但是这里有一个问题:不应该有一个选项,在设置时,要求编译器尽可能符合标准,无论它们是否与标准一致.例如,visual studio有这样一个选项,称为禁用语言扩展.但是,嘿,他们仍然允许示例2.
我希望每个人都能正确理解我的问题.MSVC允许example2是一件很棒的事情,我非常希望该功能符合标准.它不会破坏任何兼容代码,它没有什么坏处.它只是不标准.
当禁用语言扩展名设置为true时,您希望微软禁用example2吗?请注意,单词microsoft,example2等是占位符:)为什么?
再次,只是为了确保.关键点在于:编译器是否需要提供兼容版本(可选地在设置中设置)(在其限制中,例如我不是在谈论导出),因为它们提供了一个非标准的更好的替代方案,并且是也许甚至是标准的超集,因而没有破坏任何东西.
是-5整数字面量吗?或者是5一个文字,-5是一个带有一元减号的表达式,以文字为参数?当我想知道如何硬编码最小的有符号整数值时出现了这个问题.
是否可以ostream使用字符输出十六进制数字A-F而不是a-f?
int x = 0xABC;
std::cout << std::hex << x << std::endl;
Run Code Online (Sandbox Code Playgroud)
这是输出,abc而我更愿意看到ABC.
考虑以下结构:
struct Vector4D
{
union
{
double components[4];
struct { double x, y, z, t; } Endpoint;
};
};
Run Code Online (Sandbox Code Playgroud)
在我看来,我在WinApi的IPAddress结构中看到了类似的东西.我的想法是让我可以通过索引和名称来使用数组组件,例如:
Vector4D v;
v.components[2] = 3.0;
ASSERT(v.Endpoint.z == 3.0) //let's ignore precision issues for now
Run Code Online (Sandbox Code Playgroud)
在C++标准中,保证在POD结构的开头不会有"空"空间,也就是说,元素x将位于Endpoint结构的beginnig中.目前很好.但我似乎还没有找到任何保证将没有空的空间或填充,如果你愿意,之间x和y,或y和z,等等.我还没有检查出C99标准虽然.
问题是如果Endpoint结构元素之间有空格,那么这个想法就行不通了.
问题:
我是对的,确实无法保证这在C或C++中都能正常工作.
这实际上适用于任何已知的实现吗?换句话说,你知道任何不起作用的实现吗?
是否有任何标准(我的意思是不是编译器特定的)表达相同想法的方式?也许C++ 0x对齐功能可能会有所帮助?
顺便说一下,这不是我在生产代码中所做的事情,不用担心,只是好奇.提前致谢.
这个问题的灵感来自另一个问题.在尝试回答这个问题时,我明白自己有很多问题.所以......考虑以下几点:
struct S1
{
enum { value = 42 };
};
template <class T> struct S2
{
typedef S1 Type;
};
template <class T> struct S3
{
typedef S2<T> Type;
};
template <class T> struct S4
{
typedef typename T::Type::Type Type; //(1)//legal?
enum {value = T::Type::Type::value }; //(2)//legal?
};
int main()
{
S4<S3<S2<S2<S1> > > >::value;
}
Run Code Online (Sandbox Code Playgroud)
这与MSVC9.0和Online Comeau成功编译.但是,困扰我的是我不理解typename(1)中提到的内容以及为什么我们不需要typename(2).
我已经尝试过这两种语法(合成器?),我认为它应该是MSVC上的两种失败:
typedef typename T::typename Type::Type Type;
enum {value = typename T::typename Type::Type::value };
Run Code Online (Sandbox Code Playgroud)
和 …
$ 4.2/1 - "类型的左值或右值"数组"N T"或"未知T的数组"可以转换为"指向T的指针"的右值.结果是一个指向第一个元素的指针阵".
我不知道如何在初始化/声明期间获得数组类型的rvalue?
考虑以下C++程序
struct str
{
int mem;
str()
try
:mem(0)
{
throw 0;
}
catch(...)
{
}
};
int main()
{
str inst;
}
Run Code Online (Sandbox Code Playgroud)
catch块工作,即控件到达它,然后程序崩溃.我无法理解它有什么问题.
我知道C++标准明确保证了大小char,signed char和unsigned char.此外,它提供了保证,比方说,short至少是一样大的char,int大如short等,但有关的,比如说绝对值没有明确的保证,sizeof(int).这是我头脑中的信息,我和它幸福地生活在一起.然而,不久之前,我在SO中找到了一条评论(找不到它),在C long中保证至少有4个字节,而且这个要求是由C++"继承"的.是这样的吗?如果是这样,我们对C++中算术类型的大小有什么其他的隐含保证?请注意,我对这个问题中不同平台的实际保证完全不感兴趣,只是理论上的 那些.
考虑这个翻译单位:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::size_t> mp;
mp.insert(std::make_pair("hello", 42));
}
Run Code Online (Sandbox Code Playgroud)
这个翻译单元有两件事困扰着我,他们是
我刚才假设<cstddef>和<utility>必须已#include被D <string>和<map>.
这个假设有多合适?至少make_pair我认为有一个非常强大的保证,因为地图成员接口使用std::pair.因为std::size_t没有正式的保证,但是一旦你包括map或者,它很可能是可用的string.第一个风格问题是,您是否明确包含<cstddef>并<utility>在此翻译单元中?
这部分部分处理了已经包含的一些标题的不确定性.但是,问题的第二部分.假设我们有这个
//f.h
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
#include <string>
std::string f();
#endif
//f.cpp
#include "f.h"
std::string f()
{
std::string s;
return s;
}
Run Code Online (Sandbox Code Playgroud)
第二个问题是:你明确#include <string>到f.cpp吗?
我想我的问题很明确.顺便说一句.这两个问题后面都是一个很大的WHY:)谢谢.
在C编程语言中,可以在单个语句的情况下省略代码块,例如:
if(1) exit();
Run Code Online (Sandbox Code Playgroud)
现在,这只适用于条件吗?为什么这在函数的情况下无效:
void f(int a) exit();
Run Code Online (Sandbox Code Playgroud)