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

%#b with field width exceeds specified width #121

Closed
nocodo189753 opened this issue Feb 23, 2022 · 5 comments
Closed

%#b with field width exceeds specified width #121

nocodo189753 opened this issue Feb 23, 2022 · 5 comments
Assignees
Labels
bug Something isn't working resolved-on-develop A changeset fixing this issue has been commiutted to the development branch

Comments

@nocodo189753
Copy link

nocodo189753 commented Feb 23, 2022

Hi:
my test code is :

dbg("%#10b\n", 0xf);
dbg("%#10b\n", 0xff);
dbg("%#10b\n", 0x00);
dbg("%#010b\n", 0xff);
dbg("%#010b\n", 0x00);

output ('_' means space):

_____0b1111
0b11111111
____________0
0b011111111
0000000000

It seems:

  1. if val is 0, then no "0b" prefix
  2. "%#010b\n" have an extra 0, while width should be 10 ('0b' + 8bit) if I'm right

Is these a bug or I'm using it wrong?

My env:
keil mdk 5.36.0,with segger rtt output

#define dbg_log(...) fctprintf(putchar_custom_, (void *)0, __VA_ARGS__)
#define dbg_ext(...) fctprintf(putchar_custom_, (void *)1, __VA_ARGS__)
#define dbg dbg_log

void putchar_(char ch) { SEGGER_RTT_PutChar(0, ch); }
void putchar_custom_(char ch, void *arg) { SEGGER_RTT_PutChar((int)arg, ch); }

@eyalroz
Copy link
Owner

eyalroz commented Feb 25, 2022

First, thank you for filing the issue.

Second - I'm assuming this issue manifests on regular desktop machines, since I have no idea what "segger rtt" is.

Now...

%b is a non-standard specifier. I am assuming we should treat it similarly to the %x specifier, but with base 2 instead of 16 .

So,

if val is 0, then no "0b" prefix

This is how x behaves - assuming no precision is set; and that's the case also in the alternative representation #x (and thus #b.

(to be continued)

@eyalroz
Copy link
Owner

eyalroz commented Feb 25, 2022

I don't see the extra 0 you mentioned. Here are all of your testcases, with their %x equivalent printed by my printf_() and glibc's printf:

printf_("%x", 0xf)      : f
printf ("%x", 0xf)      : f
printf_("%b", 0xf)      : 1111
----
printf_("%#x", 0xf)     : 0xf
printf ("%#x", 0xf)     : 0xf
printf_("%#b", 0xf)     : 0b1111
----
printf_("%#10x", 0xf)   :        0xf
printf ("%#10x", 0xf)   :        0xf
printf_("%#10b", 0xf)   :     0b1111
----
printf_("%#10x", 0xff)  :       0xff
printf ("%#10x", 0xff)  :       0xff
printf_("%#10b", 0xff)  : 0b11111111
----
printf_("%#10x", 0x0)   :          0
printf ("%#10x", 0x0)   :          0
printf_("%#10b", 0x0)   :          0
----
printf_("%#010x", 0xff) :       0xff
printf ("%#010x", 0xff) :       0xff
printf_("%#010b", 0xff) : 0b11111111
----
printf_("%#010x", 0x0)  : 0000000000
printf ("%#010x", 0x0)  : 0000000000
printf_("%#010b", 0x0)  : 0000000000

(the single space after the : is part of the prefix and not due to the specifier replacement.)

@nocodo189753
Copy link
Author

nocodo189753 commented Feb 28, 2022

Thanks for your response.

  1. I checked the c99 standard for alternative form, it did mentioned that

For x(or X) conversion, a nonzero result has 0x(or 0X) prefixed to it.

end of question.

  1. The %#010b did output 0b011111111 in my test.

In print_integer_finalization :

// handle hash
  if (flags & (FLAGS_HASH | FLAGS_POINTER)) {
    if (!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) {
      // Let's take back some padding digits to fit in what will eventually
      // be the format-specific prefix
      if (unpadded_len < len) {
        len--;
      }
      if (len && (base == BASE_HEX)) {
        if (unpadded_len < len) {
          len--;
        }
      }
    }
   ...
}
before those code:
flags = FLAGS_HASH | FLAGS_ZEROPAD
base = BASE_BINARY
buf = '1111111100'
len = 10
unpadded_len=8

since (len && (base == BASE_HEX)) is false, this makes only 1 byte 'take backed',after prefix append buf becomes 111111110b0, an extra 0 appeared.

@eyalroz
Copy link
Owner

eyalroz commented Feb 28, 2022

I can now reproduce the issue. Not sure why I wasn't seeing it before. Expect a fix soon...

@eyalroz eyalroz changed the title "#b" problem %#b with field width exceeds specified width Feb 28, 2022
eyalroz added a commit that referenced this issue Feb 28, 2022
…`, like for `%#x`, when a precision is field width is specified and we are matching it exactly.
@eyalroz
Copy link
Owner

eyalroz commented Feb 28, 2022

@nocodo189753 : Please try the head of the develop branch and make sure the bug is resolved for you as well.

@eyalroz eyalroz self-assigned this Feb 28, 2022
@eyalroz eyalroz added bug Something isn't working resolved-on-develop A changeset fixing this issue has been commiutted to the development branch labels Feb 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working resolved-on-develop A changeset fixing this issue has been commiutted to the development branch
Projects
None yet
Development

No branches or pull requests

2 participants