Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include: When defining NDEBUG, assert will implement alignment standards #12303

Merged
merged 2 commits into from
May 17, 2024

Conversation

Gary-Hobson
Copy link
Contributor

Summary

As defined by the C standard, if NDEBUG is defined, assert should do nothing but be simply defined as:

#define assert(ignore) ((void)0)

Reference link:
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/assert.h.html

Impact

Testing

@acassis
Copy link
Contributor

acassis commented May 8, 2024

@Gary-Hobson after your modification microADB is failing here:

    if (!uv_is_active((uv_handle_t*)&client->read_pipe)) {
        /* Restart read events */
        int ret = uv_read_start((uv_stream_t*)&client->read_pipe,
            usb_uv_allocate_frame,
            usb_uv_on_data_available);
        /* TODO check return code */
        assert(ret == 0);
        UNUSED(ret);
    }

Seems like you need to replace "#define assert(f) (0)" with something like "#define assert(f) (f && 0)".

This is strange because UNUSED() should avoid the issue, but is not working!

@fjpanag
Copy link
Contributor

fjpanag commented May 8, 2024

I thought that the internal assertions, like ASSERT() and VERIFY() (not the standard assert()), were controlled by CONFIG_DEBUG_ASSERTIONS and not NDEBUG.

Also before ASSERT() was always active, and only DEBUGASSERT() was enabled/disabled depending on the build type.

Is this changed now?

@xiaoxiang781216
Copy link
Contributor

I thought that the internal assertions, like ASSERT() and VERIFY() (not the standard assert()), were controlled by CONFIG_DEBUG_ASSERTIONS and not NDEBUG.

No, DEBUGASSERT is controlled by CONFIG_DEBUG_ASSERTIONS. ASSERT, VERIFY and assert are controlled by NDEBUG.

Also before ASSERT() was always active, and only DEBUGASSERT() was enabled/disabled depending on the build type.

Is this changed now?

this patch doesn't change the assertion behavior, only the warning of unused variable may generate in the new patch if you use assert, but it's required by spec.

@xiaoxiang781216
Copy link
Contributor

@Gary-Hobson after your modification microADB is failing here:

    if (!uv_is_active((uv_handle_t*)&client->read_pipe)) {
        /* Restart read events */
        int ret = uv_read_start((uv_stream_t*)&client->read_pipe,
            usb_uv_allocate_frame,
            usb_uv_on_data_available);
        /* TODO check return code */
        assert(ret == 0);
        UNUSED(ret);
    }

Seems like you need to replace "#define assert(f) (0)" with something like "#define assert(f) (f && 0)".

can't not, since the spec require that assert shouldn't reference f when NDEBUG is defined

This is strange because UNUSED() should avoid the issue, but is not working!

Yes. @Gary-Hobson please find the reason why UNUSED doesn't work as expect.

@fjpanag
Copy link
Contributor

fjpanag commented May 9, 2024

this patch doesn't change the assertion behavior, only the warning of unused variable may generate in the new patch if you use assert, but it's required by spec.

This is not correct.

Please see how the ASSERT() definition was moved from here to here, i.e. the macro was always active before and now it is conditionally active based on NDEBUG.

If ASSERT() follows NDEBUG, then what is its difference with assert()? They are the same thing. Then why not just remove ASSERT() completely?

But as it has been discussed before in the mailing list, it is considered beneficial for the kernel to have its own assertion macros, and have the ability to control them independently from the apps.

@fjpanag
Copy link
Contributor

fjpanag commented May 9, 2024

This is not correct.

Please see how the ASSERT() definition was moved from here to here, i.e. the macro was always active before and now it is conditionally active based on NDEBUG.

Sorry, I checked again the code and it seems that I am wrong. Indeed the behavior is not changing now.

As I understand this change has already happened here.

However, the rest of the points I think that still hold. What is the value of having both ASSERT() and assert() now?

@xiaoxiang781216
Copy link
Contributor

This is not correct.
Please see how the ASSERT() definition was moved from here to here, i.e. the macro was always active before and now it is conditionally active based on NDEBUG.

Sorry, I checked again the code and it seems that I am wrong. Indeed the behavior is not changing now.

As I understand this change has already happened here.

However, the rest of the points I think that still hold. What is the value of having both ASSERT() and assert() now?

ASSERT() is an internal api, so we can always reference the argument and avoid use UNUSED macro in many places.
assert() is defined by standard, so we can't reference the argument if NDEBUG equals true and have to add UNUSED macro.

@Gary-Hobson
Copy link
Contributor Author

Gary-Hobson commented May 10, 2024

@Gary-Hobson after your modification microADB is failing here:

    if (!uv_is_active((uv_handle_t*)&client->read_pipe)) {
        /* Restart read events */
        int ret = uv_read_start((uv_stream_t*)&client->read_pipe,
            usb_uv_allocate_frame,
            usb_uv_on_data_available);
        /* TODO check return code */
        assert(ret == 0);
        UNUSED(ret);
    }

Seems like you need to replace "#define assert(f) (0)" with something like "#define assert(f) (f && 0)".

This is strange because UNUSED() should avoid the issue, but is not working!

There is no UNUSED in the source code of microADB. After I added it to the code, the compilation warning disappeared.
image

This PR ignores the compilation warning in microADB.
apache/nuttx-apps#2381

This warning has been fixed in the latest version of microADB
https://github.com/spiriou/microADB/pull/41/files

@xiaoxiang781216
Copy link
Contributor

@Gary-Hobson let's update microADB in apps to the last version.

As defined by the C standard, if NDEBUG is defined, assert should do nothing but be simply defined as:

  #define assert(ignore) ((void)0)

Reference link:
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/assert.h.html

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
@acassis acassis merged commit 20ebe0e into apache:master May 17, 2024
11 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants