简体   繁体   English

C将值分配给结构可使用调试标志,但不能使用释放标志

[英]C Assigning values to a struct works with debug flags, but not with release flags

I'm working with C and OpenGL. 我正在使用C和OpenGL。 I have a sprite struct, and a function to create a new sprite and set its' values. 我有一个精灵结构,和一个函数来创建一个新的精灵并设置其值。 The function works correctly with debug linker flags, but when I compile it with release optimizations, some sprite values are set to 0. What am I doing wrong? 该函数可以与调试链接器标志一起正常工作,但是当我使用发行版优化对其进行编译时,某些精灵值设置为0。我在做什么错?

Minimal code example (EDITED): 最小代码示例(已编辑):

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    float x;
    float y;
    float z;
} position;

typedef struct {
    float r;
    float g;
    float b;
    float a;
} colorrgba8;

typedef struct {
    float u;
    float v;
} UV;

typedef struct {
    position pos;
    colorrgba8 color;
    UV uv;
} vertex;

typedef struct {
    float x, y, z;
    float width, height;

    vertex tr;
    vertex tl;
    vertex bl;
    vertex br;
} sprite;

vertex set_position(float x, float y, float z) {
    vertex ver;
    ver.pos.x = x;
    ver.pos.y = y;
    ver.pos.z = z;
    return ver;
}

vertex set_color(float r, float g, float b, float a) {
    vertex ver;
    ver.color.r = r;
    ver.color.g = g;
    ver.color.b = b;
    ver.color.a = a;
    return ver;
}

vertex set_uv(float u, float v) {
    vertex ver;
    ver.uv.u = u;
    ver.uv.v = v;
    return ver;
}

sprite*  sprite_new(float x, float y, float z, float width, float height) {
    sprite* s = malloc(sizeof(sprite));

    s->x = x;
    s->y = y;
    s->z = z;
    s->width = width;
    s->height = height;

    s->tr = set_position(x + width, y + height, z);
    s->tr = set_uv(1.0f, 1.0f);
    s->tr = set_color(1.0f, 1.0f, 1.0f, 1.0f);

    s->tl = set_position(x, y + height, z);
    s->tl = set_uv(0.0f, 1.0f);
    s->tl = set_color(1.0f, 1.0f, 1.0f, 1.0f);

    s->bl = set_position(x, y, z);
    s->bl = set_uv(0.0f, 0.0f);
    s->bl = set_color(1.0f, 1.0f, 1.0f, 1.0f);

    s->br = set_position(x + width, y, z);
    s->br = set_uv(1.0f, 0.0f);
    s->br = set_color(1.0f, 1.0f, 1.0f, 1.0f);


    return s;
}

I call the function like this: 我这样调用该函数:

sprite* s = sprite_new(100.0f, 100.0f, -100.0f, 100.0f, 100.0f);

printf("Top right vertex pos.x: %f | Bottom left vertex pos.z: %f\n", s->tr.pos.x, s->bl.pos.z);

Output with release flags: -O2 带释放标志的输出:-O2

Top right vertex pos.x: 0.000000 | 右上角位置x:0.000000 | Bottom left vertex pos.z: 0.000000 左下角位置z:0.000000

Output with debug flags: -g -Wall -Wextra -Werror -Wwrite-strings -std=c99 -pedantic-errors 输出带调试标志:-g -Wall -Wextra -Werror -Wwrite-strings -std = c99 -pedantic-errors

Top right vertex pos.x: 200.000000 | 右上角pos.x:200.000000 | Bottom left vertex pos.z: -100.000000 左下顶点pos.z:-100.000000

You are not correctly initializing vertexes in various vertex functions. 您没有正确初始化各种顶点函数中的顶点。

In the first function that is called, set_position , you define a local vertex, and fully set member pos and its members with some values: 在第一个函数set_position ,定义一个局部顶点,并使用一些值完全设置pos及其成员:

vertex set_position(float x, float y, float z) {
    vertex ver;
    ver.pos.x = x;
    ver.pos.y = y;
    ver.pos.z = z;
    return ver;
}

however you forget to set the other members, and then the struct is returned with some uninitialized members. 但是,您忘记设置其他成员,然后返回带有一些未初始化成员的结构。 Ie the struct from the function which is partially uninitialized is assigned to s->tr . 即来自部分未初始化的函数的结构被分配给s->tr Other members' values are indeterminate. 其他成员的价值观是不确定的。 Reading those members causes undefined behavior. 读取这些成员会导致未定义的行为。 All three functions suffer from this problem. 所有这三个功能都会遇到此问题。

If you are not going to set the other elements, and the code can handle its default values then initialized the struct properly with default initializers for all its members: 如果您不打算设置其他元素,并且代码可以处理其默认值,则使用所有成员的默认初始化程序正确初始化该结构:

vertex ver = { 0 } ;

The second problem is that the next two function overwrite the member tr of struct sprite. 第二个问题是接下来的两个函数会覆盖struct sprite的成员tr For every call, tr is overwritten. 对于每个呼叫, tr被覆盖。 After the last call of function set_color , only members of tr.color are set and the rest are set to indeterminate values. 在最后一次调用set_color函数set_color ,仅设置tr.color的成员,其余成员设置为不确定的值。

s->tr = set_position(x + width, y + height, z);
s->tr = set_uv(1.0f, 1.0f);
s->tr = set_color(1.0f, 1.0f, 1.0f, 1.0f);

The rest of the code replicates these same mistakes. 其余代码重复了这些相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM