小编rid*_*ish的帖子

我如何可移植地调用C++函数,该函数在某些平台上采用char**而在其他平台上采用const char**?

在我的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)

但这有可能掩盖其他更严重的错误.

c++ portability const

91
推荐指数
4
解决办法
5369
查看次数

测试值是否与构造函数匹配

假设我有这样的数据类型:

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).

所以问题是,如何编写一个带有值和构造函数的函数,并返回值是否与构造函数匹配?

haskell

39
推荐指数
3
解决办法
2753
查看次数

交互式shell在孤立进程组中应该做什么?

简短的问题是,如果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中描述的.还有,未来怎么样?

unix shell signals process-group

25
推荐指数
1
解决办法
864
查看次数

如何避免使用符号中的多余变量?

在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)

布莱什!有更好的方法吗?

haskell do-notation

16
推荐指数
2
解决办法
545
查看次数

fixIO做什么?

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做什么以及何时应该使用它?

haskell

16
推荐指数
2
解决办法
1052
查看次数

为什么用于Unicode属性测试的C#System.Char方法有两个重载?

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])

c# unicode char

10
推荐指数
1
解决办法
884
查看次数

将整数乘以有理数而没有中间溢出

我有一个表示非负有理数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但它似乎没有提供此功能.)

c c++ rational-numbers integer-arithmetic

7
推荐指数
1
解决办法
332
查看次数

解压缩std :: array

我试图打开一个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.

  1. 为什么这可以用于clang而不是g ++?
  2. 我怎么可以轻松解压缩std::array,就像可能解开一个元组一样?

谢谢你的帮助!

c++ stl c++11

7
推荐指数
1
解决办法
1189
查看次数

Pointfree版本没有编译,但有点的版本呢?

我想写一个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)

它的工作原理!

为什么无点编译无法编译,但添加点可以使它工作?

haskell types combinators pointfree function-composition

6
推荐指数
1
解决办法
135
查看次数

std::equal 是否保证短路?

我想将以 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++ comparison language-lawyer c++11

6
推荐指数
1
解决办法
181
查看次数