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

Use strchr instead of strstr #2962

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

rootkea
Copy link
Contributor

@rootkea rootkea commented Oct 27, 2021

Found by: scan-build

src/build.c Outdated
@@ -1057,7 +1057,7 @@ gboolean build_parse_make_dir(const gchar *string, gchar **prefix)
if (string == NULL)
return FALSE;

if ((pos = strstr(string, "Entering directory")) != NULL)
if (strstr(string, "Entering directory") != NULL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this, to avoid rescanning the beginning of the string:

if ((pos = strstr(string, "Entering directory")) != NULL)
{
	// ...

	pos = strstr(pos, "/");   // instead of ... pos = strstr(string, "/");

	// ...
}

Copy link
Contributor

@andy5995 andy5995 Nov 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And is there any reason not to use strchr instead of strstr (when searching for '/')?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andy5995 Are there any tangible benefits besides maybe saving a few processor cycles or avoiding some nested function call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xiota

pos = strstr(pos, "/"); // instead of ... pos = strstr(string, "/");

Sounds good! I'll update the PR. Thanks!

Are there any tangible benefits besides maybe saving a few processor cycles or avoiding some nested function call?

Why to not save maybe a few processor cycles or not avoid some nested function call? :)

@rootkea rootkea changed the title Remove redundant code Avoid re-scanning the string Nov 25, 2021
@xiota
Copy link
Contributor

xiota commented Nov 25, 2021

Upon further reflection... the change I suggested rescans the "Entering directory" portion of the string... Should probably be (but haven't tested):

pos = strchr(pos + 18, '/');

From search, the string looks like:

make[1]: Entering directory `/mnt/lfs/sources/gcc-build'

@rootkea
Copy link
Contributor Author

rootkea commented Nov 25, 2021

pos = strchr(pos + 18, '/');

I guess we can use hard-coded values (18) as long as it's guaranteed that the string format is not going to change?

@rootkea
Copy link
Contributor Author

rootkea commented Nov 25, 2021

What do you think about pos = strchr(pos + strlen("Entering directory") + 2, "/"); where 2 for space and '

Edit - OR simply pos = strchr(pos + strlen("Entering directory '"), "/");

@xiota
Copy link
Contributor

xiota commented Nov 25, 2021

Well... it's inside an if block, so the pos is guaranteed to point to the part of the string that starts with "Entering directory".

12345678901234567890
Entering directory

I just tested the change with +18, and it captures the path correctly.

@rootkea rootkea force-pushed the redundant branch 2 times, most recently from 1e6d602 to 2e9617a Compare November 25, 2021 06:25
@xiota
Copy link
Contributor

xiota commented Nov 25, 2021

The problem with strlen("Entering directory '") is strlen runs in linear time... basically equivalent to just rescanning (that portion of) the string. (Don't know whether compilers can optimize it to a constant.)

You're also using the wrong quote char (' vs `)... so the latest push won't work anymore.

@rootkea
Copy link
Contributor Author

rootkea commented Nov 25, 2021

wrong quote char (' vs `)

Fixed now. Thanks!

The problem with strlen("Entering directory '") is strlen runs in linear time

I thought it could document the code well instead of using hard-coded number. But maybe I should add a comment instead and use the hard-coded number?

@xiota
Copy link
Contributor

xiota commented Nov 25, 2021

I thought it could document the code well instead of using hard-coded number. But maybe I should add a comment instead and use the hard-coded number?

According to internet, clang and gcc can optimize strlen to a constant. So I guess it would okay. I'd recommend leaving the space and quote out, since it's possible different implementations of make might use different quotes, especially on different operating systems.

@elextr
Copy link
Member

elextr commented Nov 25, 2021

According to internet, clang and gcc can optimize strlen to a constant.

Yeah, but depends on what -O settings distros use.

Either way it is scanning 18 chars in a loop thats reading data via a pipe from another process, which involves system calls and possibly process switches ie the difference is immaterial. I would just let it rescan for simpler code.

src/build.c Outdated Show resolved Hide resolved
@rootkea rootkea changed the title Avoid re-scanning the string Use strchr instead of strstr Nov 25, 2021
@xiota
Copy link
Contributor

xiota commented Nov 25, 2021

@rootkea Can you copy/paste the error/warning message from scan-build gives? (Since that seems to be the main motivation for this change.)

@andy5995
Copy link
Contributor

The problem with strlen("Entering directory '") is strlen runs in linear time... basically equivalent to just rescanning (that portion of) the string. (Don't know whether compilers can optimize it to a constant.)

It looks like @elextr nixed the idea of moving the pointer ahead for this case, but for future reference, I think you could use sizeof "Entering directory" instead of strlen. Because it's a constant, sizeof can be used, then the number will be known at compile-time and won't need to be computed at run-time. (Sometimes it will be important to be mindful that using the sizeof operator will give the result of the string length + 1 for the NULL terminator.

src/build.c Outdated Show resolved Hide resolved
@andy5995
Copy link
Contributor

@rootkea @xiota If you have any extra curiosity about fun with strings, you want to look at some of the functions in a couple of my small programs, such as canfigger or rmw. Keeping in mind I'm not a pro so at some later time you might find better ways to do things than I've done ;)

@rootkea
Copy link
Contributor Author

rootkea commented Nov 25, 2021

@rootkea Can you copy/paste the error/warning message from scan-build gives? (Since that seems to be the main motivation for this change.)

scan-build warned regarding redundant assignment to pos in if expression (line 1060) since on master we reassign to pos at line 1066 without using the earlier assigned value.

But now, we are passing the earlier assigned value of pos to strchr() as you suggested so assignment at line 1060 is no longer redundant.

@elextr
Copy link
Member

elextr commented Nov 25, 2021

@andy5995 that would still have the string constant in two places, if it really was worth doing do it like:

static char ed[] = "Entering Directory";
.
pos = strstr(string, ed);
.
strchr(pos + sizeof ed - 1, '/')

Note the -1 to account for the end NUL.

But as I said I don't think its worth doing.

@rootkea
Copy link
Contributor Author

rootkea commented Nov 25, 2021

@andy5995 Thanks for the pointers! I'll definitely take a look. :)

@andy5995
Copy link
Contributor

But as I said I don't think its worth doing.

@elextr , fwiw, I agree. ;)

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