几个星期前,我开始在我的SVN存储库的主干中进行更改,我认为这将是相当小的.
经过几个小时的工作,我意识到这个变化比我想象的更重要,我觉得立刻检查我的变化是太危险了,所以我做了一个分支,就像这样:
svn copy . https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
...然后做了一个svn开关,并愉快地继续在那个分支工作.到目前为止,这么好,直到我对所有变化感到高兴,并希望将它们再次合并回主干.所以我将所有更改检入my-branch,然后仔细按照此处显示的步骤进行操作......这就是我遇到麻烦的地方.因为我从本地(客户端)存储库创建了my-branch,该存储库已经有大量(未签入的)未完成的更改,所以合并不包括与这些更改对应的差异,因此存在合并中有很多很多冲突,我必须手工解决 - 这是我不想做的事情,因为如果我搞砸了就会留下虫子进入的空间.
我尝试通过减少合并期间指定的修订号来包含缺失的差异,例如通过执行a
svn merge -r2818:2932 https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
而不是预期的
svn merge -r2819:2932 https://my_svn_server/svn/blah/branches/my-branch
Run Code Online (Sandbox Code Playgroud)
...但是这没有用,因为我的分支在修订版2818中不存在,所以我只是得到一个错误:
svn: Unable to find repository location for 'https://my_svn_server/svn/blah/branches/my-branch' in revision 2818
Run Code Online (Sandbox Code Playgroud)
这就是事情的立场.我这次可以手动理清这个烂摊子,但我很好奇是否有办法处理这个问题,以便下次事情变得更好.
我能想到的一个方法是不通过复制本地(客户端)储存库,而是通过使SVN树干HEAD的副本,然后检查出我分支到一个单独的目录中创建我的分支,然后手动将我的本地(未签入)更改从trunk目录复制到my-branch目录,然后直接还原本地trunk ...但这也非常繁琐且容易出错.
当然有一种更好,更自动的方法来创建一个包含本地(未签入)更改的分支,然后将其合并回到主干中?
下面是一个C++头文件,它在g ++和clang下编译时没有错误,但是在MSVC2015下,它出错了(void) copyFrom,出错了C2027: use of undefined type 'blah::SomeOtherClass'.
我的问题是:根据C++标准,此代码是否合法?或者如果代码不正确(即因为将参数转换为(void)合法地需要的不仅仅是前向声明),那么保留我的DOxygen文档以获得copyFrom参数的好方法是什么,而不会在parameter copyFrom was never referenced我的编译器中引入不必要的警告-Output?(注意,此时SomeOtherClass无法获得完整定义,因为SomeOtherClass取决于DummyImplementation)
#ifndef blah_h
#define blah_h
namespace blah {
class SomeOtherClass;
/** Example of the problem at hand */
class DummyImplementation
{
public:
/** Dummy implemention of CopyFrom().
* @param copyFrom This parameter is ignored.
* @returns zero.
*/
int CopyFrom(const SomeOtherClass & copyFrom)
{
(void) copyFrom; // error C2027: use of undefined type 'blah::SomeOtherClass' …Run Code Online (Sandbox Code Playgroud) I'm trying to write a little program that will add mDNS CNAME aliases to my Linux device, so that it can be accessed via more than one "something.local." domain name.
该程序的预期功能与avahi-aliases Python脚本相同,但为了避免Python依赖,我试图用C++实现它.
我的代码(现在)基于Avahi源代码发行版中包含的client-publish-service.c示例.当我将该示例保持不变时,它按预期工作:特别是,我看到"MegaPrinter"出现在Mac上的Bonjour浏览器中,等等.
我的下一步是修改示例代码以添加CNAME记录而不是添加服务.所以我#ifdef了avahi_entry_group_add_service()调用并将其放入:
const int TTL = 60;
char rdata[] = "\0msli-10135114\0local"; // "msli10135114.local." is the device's normal FQDN, which I want to make aliases to
rdata[0] = 13;
rdata[14] = 5;
printf("rdata=[%s] _moduleName=[%s]\n", rdata, _moduleName);
printf("add_record: %s\n", avahi_strerror(avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, "TestX", 0x01, 0x10, 120, …Run Code Online (Sandbox Code Playgroud) 我有一些使用类型惩罚的代码,以避免必须调用成员"对象"的构造函数和析构函数,除非/直到实际需要使用该对象.
它工作正常,但在g ++ 4.4.3下,我得到了这个可怕的编译器警告:
jaf@jeremy-desktop:~$ g++ -O3 -Wall puns.cpp
puns.cpp: In instantiation of ‘Lightweight<Heavyweight>’:
puns.cpp:68: instantiated from here
puns.cpp:12: warning: ignoring attributes applied to ‘Heavyweight’ after definition
puns.cpp: In destructor ‘Lightweight<T>::~Lightweight() [with T = Heavyweight]’:
puns.cpp:68: instantiated from here
puns.cpp:20: warning: dereferencing type-punned pointer will break strict-aliasing rules
puns.cpp: In member function ‘void Lightweight<T>::MethodThatGetsCalledRarely() [with T = Heavyweight]’:
puns.cpp:70: instantiated from here
puns.cpp:36: warning: dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
我的代码尝试使用gcc的__attribute((__ may_alias__))让gcc知道潜在的别名,但是gcc似乎并不理解我想告诉它的内容.我做错了什么,或者gcc 4.4.3只是在__may_alias__属性上遇到了一些问题?
重现编译器警告的玩具代码如下:
#include <stdio.h>
#include <memory> // …Run Code Online (Sandbox Code Playgroud) 我有一个模板化的容器类,看起来像这样:
template <class ItemType> class MyContainer
{
public:
[... various methods omitted for brevity...]
void Clear()
{
ItemType defaultItem;
for (int i=0; i<_numValidItems; i++) _itemArray[i] = defaultItem;
_numValidItems = 0;
}
void FastClear()
{
_numValidItems = 0;
}
private:
int _numValidItems;
ItemType * _itemArray;
};
Run Code Online (Sandbox Code Playgroud)
如您所见,Clear()方法将容器中的每个项重置为其默认状态,这对于类型是必需的,例如,各个项目已动态分配了我希望释放Clear()调用的内部资源.
也有FastClear(),它顾名思义是更快(O(1),而不是O(N)),因为它简单地设置_numValidItems为零,并且实际上不触及任何阵列中的项目.这对于POD风格的ItemTypes很有用,但对于例如文件句柄类型则不太好.
我的问题是,是否有使用或SFINAE类似于让编译器在编译时决定,它是安全的明确()的代名词FastClear()的方式,即当的ItemType有一个平凡的析构函数?这样调用代码就不必记住调用FastClear()而不是Clear来获得加速,它会自动工作.
另外,只是为了让事情变得更加困难......我希望能够在不增加对Boost/TR1/C++ 11的依赖的情况下做到这一点.(所以调用is_pod()或has_trivial_destructor()对我来说不是很好的选择)
这是一个问题场景:我有一个C++对象,其中包含一个需要在销毁对象之前调用的Cleanup()虚方法.为了做正确的事情,这个Cleanup方法需要访问完全形成的对象(包括子类数据),所以我不能只在我自己的类的析构函数的开头调用Cleanup(),因为当我的类的时候析构函数被调用,析构函数中的任何子类都已经完成,它们可能已经释放了一些需要查看的Cleanup()数据.
显而易见的解决方案是在删除对象之前要求调用代码手动调用我的例程:
theObject->Cleanup();
delete theObject;
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案很脆弱,因为迟早有人(可能是我)会忘记调用Cleanup()并且会发生坏事.
另一个解决方案是拥有一个"holder"对象,它实现了pImpl技术来包装类,并且在删除对象之前让持有者对象的析构函数在对象上调用Cleanup(); 但是这个解决方案也不是100%理想的,因为它使得类与标准C++类的工作方式不同,并且无法在堆栈上或静态地分配对象.
所以问题是,是否有一些聪明的技术(在C++或C++ 11中)可以用来告诉编译器在调用第一个子类析构函数之前自动调用我的对象上的指定(可能是虚拟的)方法?
(想到它,自动调用Init()方法的类似机制 - 就在最后一个子类构造函数完成之后 - 也可能很方便)
我有一个玩具QML应用程序(Qt 5.7),它由以下QML页面和一些C++代码组成,允许QML在音频设备上订阅某个状态并在QML GUI中反映该状态.玩具QML看起来像这样:
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Window 2.2
Item {
id: deviceState
property bool mute1: false
property bool mute2: false
property bool mute3: false
property bool mute4: false
Component.onCompleted: {
// Call out to C++ land, to tell the server what
// control points we are interested in tracking the state of
topLevelWindow.subscribeToControlPoints("Input 1-4 Mute", deviceState);
}
// Called by C++ land to tell us the current state of
// a control point we previously subscribed …Run Code Online (Sandbox Code Playgroud) 我有一个具有2个线程的应用程序,与内核1关联的线程A和与内核2关联的线程B,内核1和内核2在同一x86套接字中。
线程A忙于整数x的旋转,线程B在某些情况下会增加x,当线程B决定增加x时,它将使x所在的缓存行无效,并根据x86 MESI协议,它将新的x存储到存储缓冲区在core2收到无效ack之前,然后在core2收到无效ack之后,core2刷新存储缓冲区。
我想知道,在core2收到无效ack之后,core2刷新是否立即存储缓冲区?我是否有可能迫使cpu用C语言执行刷新存储缓冲区?因为在我的情况下,core1旋转x的线程A应该尽早获得x新值。
我的程序中有以下简单功能:
enum {
TABLE_INDEX_TYPE_UINT8 = 0,
TABLE_INDEX_TYPE_UINT16,
TABLE_INDEX_TYPE_UINT32,
};
// inline method
uint8_t MyTable :: GetTableIndexTypeForTableSize(uint32_t tableSize) const
{
// Deliberately testing for strictly-less-than-255/65535 here,
// because 255 and 65535 are used as special sentinel values
return (tableSize < 255) ? TABLE_INDEX_TYPE_UINT8
: ((tableSize < 65535) ? TABLE_INDEX_TYPE_UINT16 : TABLE_INDEX_TYPE_UINT32);
}
Run Code Online (Sandbox Code Playgroud)
在程序的当前版本中,只要tableSize发生更改,我都会调用此方法,并将结果存储在成员变量中以便快速重用,并且效果很好。
但是,今天,我正在尝试reduce sizeof(MyTable),并且做到这一点的一种方法是摆脱不必要的成员变量。由于上述函数的缓存结果始终是可重新计算的(基于tableSize成员变量的当前值),因此我修改了代码以在需要GetTableIndexTypeForTableSize(tableSize)时调用。
这也可以正常工作(并且可以减少sizeof(MyTable)4个字节),但是在性能基准测试中却导致性能的可衡量的降低(〜5%),我相信这是因为当前的实现GetTableIndexForTableSize()包括两个分支-操作。
所以我的问题是,是否有一种聪明的方法可以重新实现上述功能,从而不需要任何分支,从而避免5%的速度下降?(我认为使用查找表将是一个坏主意,因为我将用RAM访问延迟代替分支错误预测延迟,从而使事情变得更慢)
这是一个简单的代码模式,在我们的代码库中一直困扰着我:
// in some_header_file.h
enum Color {
red = 0,
green,
blue,
max_item
};
// in some_other_file.cpp
static const char * color_names[max_item] = {
"red",
"green",
"blue"
};
std::string get_color_name(Color c) {
if ((c >= 0) && (c < max_item)) return color_names[c];
return "Unknown color";
}
Run Code Online (Sandbox Code Playgroud)
...上面的一切都很好,直到有一天,一些粗心的程序员(好吧,通常是我)过来并将一种新颜色(例如yellow)插入到Colors枚举中some_header_file.h(就在 之前max_item),但忘记还添加新颜色的字符串(例如)到中数组"yellow"的末尾。color_names[max_item]some_other_file.cpp
发生这种情况后,代码可以正常编译,没有错误或警告,但将来的调用get_color_name(yellow)(最好的情况下)不会返回预期的结果,或者(最坏的情况下)调用未定义的行为,甚至可能崩溃。
我希望在编译时捕获这个错误,这样我就可以避免在更新枚举时引入运行时错误。C++ 中有没有一种方法可以在编译时强制执行初始化字符串的数量color_names必须等于数组的长度(即max_item)?
c++ ×7
arrays ×1
branch ×1
c ×1
c++11 ×1
client ×1
cname ×1
conditional ×1
destructor ×1
doxygen ×1
enums ×1
gcc ×1
linux ×1
merge ×1
optimization ×1
properties ×1
qml ×1
qt ×1
sfinae ×1
svn ×1
type-punning ×1
visual-c++ ×1