【问题标题】:Why this code breaks when optimizations are on?为什么在优化时这段代码会中断?
【发布时间】:2014-06-04 11:46:33
【问题描述】:

开启优化会破坏设置地图的代码。它被设置为 NULL 而不是正确的值。我是否在不知情的情况下调用了未定义的行为?

Valgrind 不会报告任何无效的读/写。我正在使用 gcc (Debian 4.8.2-14) 4.8.2

static Map *decode_message(Message message)
{
    Map *map = message.content;
    map->blocks = (Color *)(map + 1);
}

static void *network_game_handler(void *ignore)
{
    Network_Message server_reply, out_msg = NET_OK;

    if(read_all(&server_reply, sizeof server_reply) == ERROR){
        if(error_callback != NULL)
            error_callback();

        close(sockfd);
        return NULL;
    }

    while(server_reply == NET_WAIT){
        if(write_all(&out_msg, sizeof out_msg) == ERROR){
            if(error_callback != NULL)
                error_callback();

            close(sockfd);
            return NULL;
        }
        if(read_all(&server_reply, sizeof server_reply) == ERROR){
            if(error_callback != NULL)
                error_callback();

            close(sockfd);
            return NULL;
        }
    }

    if(server_reply == NET_ERROR){
        if(error_callback != NULL)
            error_callback();

        close(sockfd);
        return NULL;
    }

    if(server_reply == NET_START){
        out_msg = NET_START;
        if(write_all(&out_msg, sizeof out_msg) == ERROR){
            if(error_callback != NULL)
                error_callback();

            close(sockfd);
            return NULL;
        }
    }

    else {
        if(error_callback != NULL)
            error_callback();

        close(sockfd);
        return NULL;
    }

    network_game_ready = 1;

    void *last_msg = NULL;
    Message current_msg;

    while(!game_handler_stop){
        out_msg = NET_DATA;
        if(write_all(&out_msg, sizeof out_msg) == ERROR)
            goto error;

        Message msg = encode_message((Map *)map);
        if(msg.content == NULL)
            goto error;

        if(send_message(msg) == ERROR){
            destroy_message(msg);
            goto error;
        }

        destroy_message(msg);

        if(read_all(&server_reply, sizeof server_reply) == ERROR)
            goto error;

        if(server_reply == NET_STOP){
            if(stop_callback != NULL)
                stop_callback();

            engine_set_adversary_map(NULL);
            free(last_msg);
            close(sockfd);
            return NULL;
        }

        if(server_reply == NET_ERROR)
            goto error;

        if(server_reply == NET_DATA)
            if((current_msg = receive_message()).content == NULL)
                goto error;

        ///////
        ////////    This line is where the problem happens
        ///////
        engine_set_adversary_map(decode_message(current_msg));
        printf("Setting adversary map to %zu\n", decode_message(current_msg));
        free(last_msg);
        last_msg = current_msg.content;
    }

    out_msg = NET_STOP;
    write_all(&out_msg, sizeof out_msg);

    engine_set_adversary_map(NULL);
    free(last_msg);
    close(sockfd);  
    return NULL;

    error:
    engine_set_adversary_map(NULL);
    if(error_callback != NULL)
        error_callback();

    free(last_msg);
    close(sockfd);
    return NULL;
}

【问题讨论】:

    标签: c gcc


    【解决方案1】:

    显然,您希望能够处理decode_message() 的返回值,但是它无法返回任何内容。如果您启用了-Wreturn-type 警告,GCC 会警告您缺少 return 语句。如果您使用-Wall,则会启用此功能。

    您可能打算返回map

    static Map *decode_message(Message message)
    {
        Map *map = message.content;
        map->blocks = (Color *)(map + 1);
        return map;
    }
    

    【讨论】:

    • 非常感谢,不知道怎么没看到。我可能应该在睡觉了。
    猜你喜欢
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多