几代人一直在问这个问题的变种,但是尽管写了一些相当复杂的Windows脚本,我似乎无法找到如何使它们真正沉默.
以下是我当前脚本之一的摘录:
@ECHO OFF
SET scriptDirectory=%~dp0
COPY %scriptDirectory%test.bat %scriptDirectory%test2.bat
FOR /F %%f IN ('dir /B "%scriptDirectory%*.noext"') DO (
del "%scriptDirectory%%%f"
)
ECHO
Run Code Online (Sandbox Code Playgroud)
结果是:
C:\Temp> test.bat
1 file(s) copied.
File Not Found
Echo is off.
C:\Temp>
Run Code Online (Sandbox Code Playgroud)
而"1个文件被复制".只是很烦人,"找不到文件"让用户认为出了问题(它没有 - 没有文件没问题).
现在,我已经对此持续了大约一个星期,并且在论坛之后搜索了论坛,以便清楚地解释如何从C发送char*到FORTRAN.为了让事情更令人沮丧,从FORTRAN向C发送char*参数是直截了当的......
从FORTRAN发送char*参数到C(这很好):
// The C header declaration (using __cdecl in a def file):
extern "C" double GetLoggingValue(char* name);
Run Code Online (Sandbox Code Playgroud)
来自FORTRAN:
! The FORTRAN interface:
INTERFACE
REAL(8) FUNCTION GetLoggingValue [C, ALIAS: '_GetLoggingValue'] (name)
USE ISO_C_BINDING
CHARACTER(LEN=1, KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: name
END FUNCTION GetLoggingValue
END INTERFACE
! Calling the function:
GetLoggingValue(user_name)
Run Code Online (Sandbox Code Playgroud)
当尝试使用类似逻辑从C返回char*时,我遇到问题后出现问题.我觉得应该尝试的一个尝试是:
// The C declaration header (using __cdecl in a def file):
extern "C" const char* GetLastErrorMessage();
Run Code Online (Sandbox Code Playgroud)
和FORTRAN接口:
INTERFACE
FUNCTION GetLastErrorMessage [C, ALIAS: '_GetLastErrorMessage'] ()
USE ISO_C_BINDING
CHARACTER(LEN=1, KIND=C_CHAR), DIMENSION(255), :: …Run Code Online (Sandbox Code Playgroud) 我原以为这可以通过谷歌轻松解决问题,但我似乎无法找到明确的(甚至是推测性的)答案:
使用比较器语句时,隐式转换的顺序是什么?
int i = -1;
size_t t = 1;
bool result = i < t;
Run Code Online (Sandbox Code Playgroud)
这相当于:
bool result = i < int(t); // equals true
Run Code Online (Sandbox Code Playgroud)
要么:
bool result = size_t(i) < t; // equals false
Run Code Online (Sandbox Code Playgroud)
这是问题的简单部分 - 第二部分是"一般规则是什么",因为它可能是:
所有三个看起来都是合理的,尽管第二个会产生与大多数人直观期望的行为明显不同的行为.
当你将int与size_t进行比较时,VC++编译器似乎认为它值得一个3级警告 - 然而当你从返回size_t的函数返回一个负数时它只给出一个4级警告(这导致一个数字只是超过返回的最大整数的一半).
为了摆脱所有4级警告,我现在无论如何都明确地投了一切,但我想知道"真相".这必须在某处定义......
我们这里有一个非常大的程序,它混合了C++和FORTRAN(对不起).我的一次签到导致整个应用程序急剧减速(即两倍或更多) - 即使在代码中不受我的更改影响的区域也是如此.
事实:
几乎每个模块都减慢了相似的数量 - 甚至是那些不使用我的代码的模块.
可执行文件大约增加6%.
签入之间未更改元数据.
IDE /编译器处于发布模式的VS2010.
一些.lib文件的大小增加了一倍或三倍.
我看了一个大小增加了三倍的.lib文件,只有两个变化:
a)我已经包含了一个大型的头文件,而该文件又包含许多其他文件 - 其中一些包含中等复杂的内联代码."附加包含目录"已经从非一个或一个变为大约7个,因为每个头文件#include一个或多个其他头文件.
b)我从这个头文件中调用了4个函数,但是这些函数在运行期间没有被调用(即它们的执行不能减慢代码速度,但可能会包含它们).
尽管在论坛中搜索包含头文件是否会减慢执行速度(而不是编译),但我找不到一篇相关的文章.我的问题是:
?任何形式的头文件(声明或内联)的#inclusion是否会减慢代码执行速度?
?内联代码的执行速度是否存在定性或定量差异(我知道'内联'只是对编译器的建议)?
?.lib大小,.exe大小和执行速度之间有什么相关性(我期待这里有很多不同且相互矛盾的相关性)?
?将重构一些头文件,以便他们不需要包含其他文件(通过将这些包含放入.cpp文件,从而减少我的'其他包含目录')改善我的情况,你觉得呢?
我想最后一个问题是问题的关键,因为它需要付出很多努力......
我们在一些英特尔FORTRAN代码中遇到了一些奇怪的崩溃,我最终将这条线跟踪到:
L_F = EXP(-L_B2*L_BETASQ*L_DS)
Run Code Online (Sandbox Code Playgroud)
-L_B2*L_BETASQ*L_DS项的评估值约为-230.碰巧,EXP(-230)的评估值约为1e-100.在所有其他已知情况下,L_DS要小得多,导致EXP的最小(已知)返回约为1e-50,这不会导致错误.
一旦FORTRAN评估条款EXP(-230),您就得到:
forrtl: severe (157): Program Exception - access violation
Image PC Routine Line Source
Run Code Online (Sandbox Code Playgroud)
但没有其他信息.
异常157通常与互操作性有关,并且您无法在FORTRAN中调试EXP,因为它无法找到特定的.c文件 - 这可能意味着EXP在C中实现(我觉得这很令人惊讶).
我的假设是FORTRAN在C中实现了EXP,但是接口不能将小于1e-100的浮点数转换为REAL(4)s.正如我之前认为浮点数和REAL(4)s在字节方面相同,我无法支持这个假设 - 我无法找到任何关于它的东西.
在我关闭这个错误之前,任何人都可以确认或否认我的假设 - 或者向我提供另一个假设吗?
最好的祝福,
麦克风
编辑: 我将把这个问题标记为已回答,因为高绩效标记已回答了当前的问题.
不幸的是,我的假设是不正确的 - 我试图将这个问题陷入困境:
L_ARG = L_B2*L_BETASQ*L_DS
IF (L_ARG .GT. 230.0) THEN
L_F = 0.0
ELSE
L_F = EXP(-L_ARG)
ENDIF
Run Code Online (Sandbox Code Playgroud)
不幸的是,现在(显然)例外发生在L_ARG .GT中.230.0条款.这或者意味着Release模式下的调试比我想象的要糟糕,或者它是某种"存储的"浮点错误(当将float输入到stringstream时,请参阅"浮点无效操作").
如果这个问题已经得到回答,我很抱歉 - 我已经搜索过了,但由于通过引用传递的一般性问题的数量很多,这是一个难以找到的搜索词.
我遇到的问题是,当我编译这类东西时,我得到了4级警告:
class MyClass
{
public:
MyClass() {};
};
void DoSomethingToMyClass(MyClass& my_class_reference);
void MyRoutine()
{
DoSomethingToMyClass(MyClass());
};
Run Code Online (Sandbox Code Playgroud)
警告(C4239)基本上表示从实例到引用有一个狡猾的演员表.我从仔细检查中学到了不要注销4级警告,因为他们中的许多人已经识别出我(和其他人)代码中的错误,例如返回-1作为size_t(知道什么size_t(-1)的奖励积分)实际上是).
任何人都可以向我解释上面的代码实际上会做什么吗?我最偏执的理论是:
另一个极端是C4239总能被忽略......
*[类似情况是有人默认参考时:
void DoSomethingToMyClass(MyClass& my_class_reference=MyClass());
Run Code Online (Sandbox Code Playgroud)
这会生成相同的警告,但在另一个主题中部分涵盖.]*
编辑:
谢谢你的快速反应,伙计们.对不起:应该在Visual Studio中提到它是VC++.
我进行了相当好的搜索,尽管有很多类似的问题,但我不认为答案适用。
我有一个相当低效的正则表达式来搜索相当大的字符串。我已经在http://regexpal.com上使用精确的正则表达式和字符串对其进行了测试,它几乎立即返回了正确的答案。
具有相同输入的 C# Regex 模块挂起 - 或者至少我留了 10 分钟来完成 regexpal 可以在几分之一秒内完成的工作。
Regex 的 C# 实现效率是否明显低于http://regexpal.com,还是真的挂了?正则表达式用于搜索由未知行数分隔的两个关键字:
"KEYWORD1(.|\r|\n)+KEYWORD2\t +.+"
Run Code Online (Sandbox Code Playgroud)
该字符串长 830 行,每行大约 30 个字符。
问这个问题我觉得自己像个傻瓜,因为这是我能想到的最简单的例子,但它让我受不了。
我已经实现了一个非常基本的控制台和文件记录器:
auto logger = spdlog::basic_logger_mt("console and file logger", filepath);
#ifdef NDEBUG
spdlog::set_level(spdlog::level::info); // Set global log level to info
#else
spdlog::set_level(spdlog::level::trace); // Set global log level to everything
#endif
spdlog::set_pattern("%^%l: %v%$"); // see https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
spdlog::flush_on(spdlog::level::info);
Run Code Online (Sandbox Code Playgroud)
这以颜色完美地写入控制台,但尽管它创建了日志文件,但它从不写入。
我想尝试手动刷新它,但没有 spdlog::flush。
我最初用两个接收器(一个控制台,一个文件)实现了这个,并且有一个类似的问题:除非在这种情况下它会将第一条(也是唯一的第一条)消息写入日志文件,只要它是一个错误。
很抱歉问这么无聊的问题...
- - - - - - - - - - - - - - - 编辑 - - - - - - - - - - --------------------
尝试 1(来自多接收器示例):
// Creating console logger --------------------
auto …Run Code Online (Sandbox Code Playgroud) 我一直在使用VS10来构建一个dll,但我想证明它也可以在Eclipse中完成.
Eclipse中的明显症状是链接器因激怒而失败:
LINK : fatal error LNK1104: cannot open file 'C:\Program.obj'
Run Code Online (Sandbox Code Playgroud)
这可能是因为某些东西没有保护C:\ Program Files(x86)...参数中的空格,我有几个.
我可以通过将命令复制到CMD提示符并手动在包含空格的参数周围添加引号来运行命令,因此我99.9%确定问题是Eclipse没有在这些参数周围添加引号.该工作的命令是:
link /DLL /debug /nologo /OUT:PIDExternalController.dll main.obj C:\Opt\Bladed\Main\Test\Code\ExternalController\Debug\ExternalControllerApi.lib "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\delayimp.lib" "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\Kernel32.Lib" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\oldnames.lib" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\msvcrt.lib"
Run Code Online (Sandbox Code Playgroud)
Eclipse的命令回显是相同的,但没有引号(虽然这不一定证明什么,因为编译器回显没有显示它实际上使用的引号).
我找不到任何选项或合法的机制来让Eclipse在链接调用周围加上引号 - 但这必须是一个常见的要求.我错过了一些明显的事吗?