相关疑难解决方法(0)

为什么printf("%f",0); 给出未定义的行为?

该声明

printf("%f\n",0.0f);
Run Code Online (Sandbox Code Playgroud)

打印0.

但是,声明

printf("%f\n",0);
Run Code Online (Sandbox Code Playgroud)

打印随机值.

我意识到我表现出某种未定义的行为,但我无法弄明白为什么具体.

所有位都为0的浮点值仍然有效float,值为0.
float并且int在我的机器上具有相同的大小(如果它甚至相关).

为什么使用整数文字而不是浮点文字printf会导致此行为?

如果我使用PS,可以看到相同的行为

int i = 0;
printf("%f\n", i);
Run Code Online (Sandbox Code Playgroud)

c c++ printf undefined-behavior implicit-conversion

86
推荐指数
7
解决办法
6931
查看次数

有没有办法在C中实现闭包

我希望这可以工作,但它没有:

#include <stdio.h>

typedef struct closure_s {
  void (*incrementer) ();
  void (*emitter) ();
} closure;

closure emit(int in) {

  void incrementer() {
    in++;
  }

  void emitter() {
    printf("%d\n", in);
  }

  return (closure) {
    incrementer,
    emitter
  };
}

main() {
  closure test[] = {
    emit(10),
    emit(20)
  };

  test[0] . incrementer();
  test[1] . incrementer();

  test[0] . emitter();
  test[1] . emitter();
}
Run Code Online (Sandbox Code Playgroud)

它实际上编译和1个实例不工作...但第二个失败.知道如何在C中获得闭包吗?

真的很棒!

c closures

32
推荐指数
5
解决办法
2万
查看次数

为什么在调用printf之前%eax归零?

我想拿起一点x86.我正在使用gcc -S -O0在64位mac上进行编译.

C中的代码:

printf("%d", 1);
Run Code Online (Sandbox Code Playgroud)

输出:

movl    $1, %esi
leaq    LC0(%rip), %rdi
movl    $0, %eax        ; WHY?
call    _printf
Run Code Online (Sandbox Code Playgroud)

我不明白为什么在调用'printf'之前%eax被清除为0.由于printf返回打印的字符数量为%eax我最好的猜测,因此将其归零以准备它,printf但我认为printf必须负责准备它.而且,相反,如果我调用自己的功能int testproc(int p1),则gcc认为没有必要准备%eax.所以我想知道为什么gcc对待printftestproc不同.

macos assembly gcc x86-64 cpu-registers

32
推荐指数
3
解决办法
7918
查看次数

C++跳转到其他方法执行

在我的C++ JNI-Agent项目中,我正在实现一个函数,该函数将被赋予可变数量的参数并将执行传递给另一个函数:

// address of theOriginalFunction
public static void* originalfunc;

void* interceptor(JNIEnv *env, jclass clazz, ...){

    // add 4 to the function address to skip "push ebp / mov ebp esp"
    asm volatile("jmp *%0;"::"r" (originalfunc+4));

    // will not get here anyway
    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

上面的函数只需要跳转到:

JNIEXPORT void JNICALL Java_main_Main_theOriginalFunction(JNIEnv *env, jclass clazz, jboolean p1, jbyte p2, jshort p3, jint p4, jlong p5, jfloat p6, jdouble p7, jintArray p8, jbyteArray p9){
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常,原始函数可以正确读取所有参数(使用包括数组在内的9种不同类型的参数进行测试).

但是,在从拦截器跳入原始函数之前,我需要做一些计算.但是,在这里我观察到有趣的行为.

void* interceptor(JNIEnv *env, jclass …
Run Code Online (Sandbox Code Playgroud)

c++ java-native-interface stack javaagents

14
推荐指数
1
解决办法
903
查看次数

vararg函数如何找出机器码中的参数数量?

printf这样的可变函数如何找出它们得到的参数数量?

显然,参数的数量不会作为(隐藏)参数传递(请参阅asm示例中的printf调用).

有什么诀窍?

assembly printf variadic abi calling-convention

11
推荐指数
4
解决办法
5285
查看次数

va_list 还在 C++ 中使用吗?还是鼓励使用 template&lt;typename... T&gt; ?

在 C 中,定义可变长度参数的唯一方法是使用省略号声明其原型并使用va_list, va_start, va_arg,va_end来提取它们。就像printf系列和scanf系列一样。

在 C++11 中,引入了一种新方法,如下所示。

template <typename T, typename... MoreT>
void func(T arg, MoreT... args){
    // Do some stuff
    func(args);
}
Run Code Online (Sandbox Code Playgroud)

每种方法的优点和缺点是什么?在 C++ 中是否不鼓励使用或鼓励它们中的任何一个?

c++ ellipsis variadic-functions c++11

9
推荐指数
1
解决办法
2364
查看次数

va_list 参数实际上不是 va_list

尝试编译此代码时

#include <stdarg.h>

void bar_ptr(int n, va_list *pvl) {
    // do va_arg stuff here
}

void bar(int n, va_list vl) {
    va_list *pvl = &vl; // error here
    bar_ptr(n, pvl);
}

void foo(int n, ...) {
    va_list vl;
    va_list *pvl = &vl; // fine here
    va_start(vl, n);
    bar(n, vl);
    va_end(vl);
}

int main() {
    foo(3, 1, 2, 3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC 编译器会initialization from incompatible pointer typebar函数中打印一条警告。相同的语句在foo.

似乎 type 的 agument 的类型va_list不是 …

c variadic-functions

8
推荐指数
1
解决办法
199
查看次数

C将参数作为void-pointer-list传递给LoadLibrary()中的导入函数

我的问题是我想创建一个通用命令行应用程序,可用于加载库DLL,然后调用库DLL中的函数.函数名称在命令行中指定,参数也在实用程序命令行中提供.

我可以从使用该LoadLibrary()函数动态加载的DLL访问外部函数.一旦加载了库,我就可以获得一个指向函数的指针,GetProcAddress()我希望用命令行中指定的参数调用该函数.

我可以将一个void-pointer-list传递给函数指针,该函数指针是由LoadLibrary()类似下面示例的函数返回的?

为了简化示例代码,我删除了错误检查.有没有办法让这样的工作:

    //Somewhere in another dll
    int DoStuff(int a, int b)
    {
        return a + b;
    }
    int main(int argc, char **argv)
    {
        void *retval;
        void *list = argv[3];
        HMODULE dll;
        void* (*generic_function)(void*);

        dll = LoadLibraryA(argv[1]);

        //argv[2] = "DoStuff"
        generic_function = GetProcAddress(dll, argv[2]);

        //argv[3] = 4, argv[4] = 7, argv[5] = NULL
        retval = generic_function(list);
    }

如果我忘记提及必要的信息,请告诉我.提前致谢

c c++ winapi pointers function-pointers

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

可变C函数中的空值

如果我定义了一个可变函数:

#include <stdio.h>
#include <stdarg.h>

int f(char*s,...)
{ 
    va_list ap;
    int i=0;
    va_start(ap, s);
    while(s)
    {
       printf("%s ", s);
       i++;
       s=va_arg(ap,char*);
    }
    va_end(ap);
    return i;
}

int main()
{ 
    return f("a","b",0);
}
Run Code Online (Sandbox Code Playgroud)

gcc(linux x64)编译这个,exe运行并打印"ab".

有没有需要像以下一样的演员:

return f("a","b",(char*)0)
Run Code Online (Sandbox Code Playgroud)

在共同的系统上?

c variadic-functions

3
推荐指数
2
解决办法
192
查看次数