在我的Linux(和OS X)机器上,该iconv()
函数具有以下原型:
size_t iconv (iconv_t, char **inbuf...
Run Code Online (Sandbox Code Playgroud)
而在FreeBSD上它看起来像这样:
size_t iconv (iconv_t, const char **inbuf...
Run Code Online (Sandbox Code Playgroud)
我希望我的C++代码能够在两个平台上构建.C编译器,传递char**
用于一个const char**
参数(或反之亦然)通常发射一个单纯的警告; 但是在C++中,这是一个致命的错误.因此,如果我传递一个char**
,它将无法在BSD上编译,如果我传递const char**
它将无法在Linux/OS X上编译.如何编写可编译在两者上的代码,而无需尝试检测平台?
我有一个(失败的)想法是提供一个覆盖标题提供的任何本地原型:
void myfunc(void) {
size_t iconv (iconv_t, char **inbuf);
iconv(foo, ptr);
}
Run Code Online (Sandbox Code Playgroud)
这个失败是因为iconv
需要C链接,你不能放在extern "C"
一个函数内(为什么不呢?)
我想出的最好的工作思路是抛出函数指针本身:
typedef void (*func_t)(iconv_t, const char **);
((func_t)(iconv))(foo, ptr);
Run Code Online (Sandbox Code Playgroud)
但这有可能掩盖其他更严重的错误.
假设我有这样的数据类型:
data NumCol = Empty |
Single Int |
Pair Int Int |
Lots [Int]
Run Code Online (Sandbox Code Playgroud)
现在我希望从a中过滤出与给定构造函数匹配的元素[NumCol]
.我可以写,比方说Pair
:
get_pairs :: [NumCol] -> [NumCol]
get_pairs = filter is_pair
where is_pair (Pair _ _) = True
is_pair _ = False
Run Code Online (Sandbox Code Playgroud)
这有效,但它不是通用的.我必须写一个单独的功能is_single
,is_lots
等等.
我希望我能写:
get_pairs = filter (== Pair)
Run Code Online (Sandbox Code Playgroud)
但这仅适用于不带参数的类型构造函数(即Empty
).
所以问题是,如何编写一个带有值和构造函数的函数,并返回值是否与构造函数匹配?
简短的问题是,如果shell在没有tty的孤立进程组中应该怎么办?但我建议阅读这个长问题,因为它很有趣.
这是一个有趣而令人兴奋的方式,使用您最喜欢的外壳将您的笔记本电脑变成便携式空间加热器(除非您是其中一个tcsh怪人):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这会导致bash将CPU固定在100%.zsh和鱼做同样的事情,而ksh和tcsh笨拙地谈论工作控制然后龙骨,这有点好,但并不多.哦,这是一个与平台无关的罪犯:OS X和Linux都受到了影响.
我的(可能是错误的)解释如下:子shell检测到它不在前台:tcgetpgrp(0) != getpgrp()
.因此它试图阻止自己:killpg(getpgrp(), SIGTTIN)
.但它的进程组是孤立的,因为它的父进程(C程序)是领导者并且死了,并且发送给孤立进程组的SIGTTIN刚刚被删除(否则什么都不能再启动它).因此,子shell不会停止,但它仍然在后台,所以它会立即再次完成.冲洗并重复.
我的问题是,命令行shell如何检测这种情况,它做什么是正确的?我的想法是shell尝试read
从stdin,如果read给它EIO就退出.
谢谢你的想法!
编辑:我尝试在/ dev/tty上执行零长度读取(),并且成功,这很糟糕.为了获得EIO,我实际上必须准备从/ dev/tty读取一些数据.
编辑:我的另一个想法是kill(getpgrp(), 0)
.如果进程组是孤立的,那么我相信这将永远失败.但是,它也可能失败,因为我没有权限发信号通知会话负责人.
编辑:对于后来发现这个的人,我最终做的是在https://github.com/fish-shell/fish-shell/issues/422中描述的.还有,未来怎么样?
在Haskell do-notation块中说,我希望有一个变量来is_root
指示我是否是root:
import System.Posix.User
main = do
uid <- getRealUserID
is_root <- return $ uid == 0
Run Code Online (Sandbox Code Playgroud)
那个讨厌的uid
变量只用在那个地方.我希望我可以这样写:
main = do
is_root <- getRealUserID == 0
Run Code Online (Sandbox Code Playgroud)
但当然不会编译.
我怎样才能摆脱多余的变量uid
呢?这是我提出的最好的:
import System.Posix.User
main = do
is_root <- getRealUserID >>= return . ((==) 0)
Run Code Online (Sandbox Code Playgroud)
布莱什!有更好的方法吗?
该System.IO文档包含一个神秘的,未公开的函数fixIO
.它的来源只会增加神秘感:
fixIO :: (a -> IO a) -> IO a
fixIO k = do
m <- newEmptyMVar
ans <- unsafeInterleaveIO (takeMVar m)
result <- k ans
putMVar m result
return result
Run Code Online (Sandbox Code Playgroud)
这似乎与取消引用NULL(从空的MVar读取)相当.确实,尝试一下:
import System.IO
main = fixIO $ \x -> putStrLn x >> return x
Run Code Online (Sandbox Code Playgroud)
导致错误"线程在MVar操作中无限期地被阻塞"
除了Simon Peyton-Jones本人提供的15年前的消息之外,搜索没有任何结果,他提供了上述来源,并希望它能使意义明确(而且我在这里).
有人可以对此有所了解吗?fixIO做什么以及何时应该使用它?
在System.Char的方法中,我们看到两种方法来检查字符是否是符号:
public static bool IsSymbol(string s, int index)
public static bool IsSymbol(char c)
Run Code Online (Sandbox Code Playgroud)
同样适用于其他财产测试:IsLower,IsLetter等
为什么会出现这种重复?没有任何理由,更喜欢Char.IsSymbol(s, idx)
了Char.IsSymbol(s[idx])
?
我有一个表示非负有理数p/q的结构:
struct rational {
uint64_t p;
uint64_t q; // invariant: always > 0
};
Run Code Online (Sandbox Code Playgroud)
我想用uint64乘以理性n
,得到一个整数结果,向下舍入.也就是说,我想计算:
uint64_t m = (n * r.p)/r.q;
Run Code Online (Sandbox Code Playgroud)
同时避免中间溢出n * r.p
.(当然最终结果可能会溢出,这是可以接受的.)
我怎样才能做到这一点?有没有办法在没有高倍数的情况下做到这一点?
(我查看了boost :: rational但它似乎没有提供此功能.)
我试图打开一个std::array
通道std::tie
:
#include <tuple>
#include <array>
int main() {
std::array<int, 3> arr = {1, 2, 3};
int a, b, c;
std::tie(a, b, c) = arr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这适用于clang,但无法在g ++ 5.4中编译:no match for ‘operator=’
.编译选项是-std=c++11
.
std::array
,就像可能解开一个元组一样?谢谢你的帮助!
我想写一个Haskell函数,它返回一个附加到自身计数次数的列表(比如lst * count
在Python中).
我的第一次尝试是:
self_append_n :: Int -> [a] -> [a]
self_append_n = concat . replicate
Run Code Online (Sandbox Code Playgroud)
我的理由是replicate
接受一个计数和一个值,并产生一个值列表.当值本身就是一个列表时,剩下的就是将列表连接在一起.但是,这给出了一个令人困惑的错误:
Couldn't match type `[a0]' with `[a] -> [a]'
Expected type: [[a0]] -> [a] -> [a]
Actual type: [[a0]] -> [a0]
In the first argument of `(.)', namely `concat'
In the expression: concat . replicate
In an equation for `self_append_n':
self_append_n = concat . replicate
Run Code Online (Sandbox Code Playgroud)
然后我写了一个有点版本:
self_append_n a b = concat $ replicate a b
Run Code Online (Sandbox Code Playgroud)
它的工作原理!
为什么无点编译无法编译,但添加点可以使它工作?
我想将以 null 结尾的字符串与字符串文字进行比较。我希望使用std::equal
并且很好奇这段代码是否根据 C++ 标准定义良好:
#include <algorithm>
bool is_foo(const char *str) {
const char *lit = "foo";
return std::equal(lit, lit + 4, str);
}
Run Code Online (Sandbox Code Playgroud)
如果std::equal
保证在第一个不匹配处停止,那么即使str
长度 < 3,这个代码对我来说似乎也是定义的。如果没有这样的保证,那么我认为这可能会取消引用超过str
导致 UB 的末尾。
如果 C++ 规范对此有任何规定怎么办?谢谢你的帮助!
c++ ×4
haskell ×4
c++11 ×2
c ×1
c# ×1
char ×1
combinators ×1
comparison ×1
const ×1
do-notation ×1
pointfree ×1
portability ×1
shell ×1
signals ×1
stl ×1
types ×1
unicode ×1
unix ×1