LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-28-2023, 06:55 PM   #1
errigour
Member
 
Registered: May 2009
Posts: 366

Rep: Reputation: 6
c programming function variable ...


Hey can someone tell me how to put the function variable ... to use? honestly I want max function to be able to take any number of variables and tell me the maximum number. is that possible? and why do i have to put a variable before ...? it wouldn't let me just do long long int max(...). Would i have to use assembly for something like that and if so could someone show me a sample assembly program that would compile for 64 bit.

Code:
#include <stdio.h>

long long int max(int argc, ...)
{

}

int
main (int argc, char *argv[])
{
    max(27, 45, 30, 98, 52);
}

Last edited by errigour; 04-28-2023 at 07:03 PM.
 
Old 04-28-2023, 07:06 PM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,237

Rep: Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322
This example looks pretty good to me:

https://www.tutorialspoint.com/c_sta...o_va_start.htm

And if you want something more boring:

https://www.gnu.org/software/libc/ma...Functions.html
 
Old 04-28-2023, 07:31 PM   #3
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
what if i wanted to make my own va_start and stuff without using those functions is it possible?
 
Old 04-28-2023, 07:41 PM   #4
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
like im trying to make a max function to use in c but i think i have to use assembly for it cause that gnu webpage says it cant be done with c. and I don't even want the first argument argc either. just want a function that will take any long long integers and tell me the max one.
 
Old 04-28-2023, 07:41 PM   #5
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
Ive seen it done in other programs so i know it can be done.
 
Old 04-28-2023, 07:53 PM   #6
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
nm im just gonna mark this as solved cause i got it to work with va list i was just trying to write my own library.
 
Old 04-28-2023, 10:10 PM   #7
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,784

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Quote:
Originally Posted by errigour View Post
what if i wanted to make my own va_start and stuff without using those functions is it possible?
You can't write your own va_start in pure C, because it depends on the compiler's/platform's calling convention.
 
Old 04-28-2023, 11:34 PM   #8
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
In C, you cannot tell how many arguments were passed to the variadic function. On the other hand, in Assembly, you cannot tell how many arguments were passed to the variadic function.
 
Old 04-29-2023, 09:14 AM   #9
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,925

Rep: Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320Reputation: 7320
https://stackoverflow.com/questions/...argc-char-argv
you can pass argc and argv directly to your max function, do not need to use va_list and friends if you don't want to.
But you need both of them (argv and argc), the pointer to the input list and the number of args. Otherwise you will not be able to handle them.
 
Old 04-29-2023, 10:14 AM   #10
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,141
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Quote:
I want max function to be able to take any number of variables and tell me the maximum number. is that possible
Ok, I'll play.

Code:
#include <stdio.h>
#include <limits.h>
#include <stdarg.h>

int max(int args, ...) {
    int i, max, cur;
    va_list valist;
    va_start(valist, args);    
    max = INT_MIN;
    
    for(i=0; i<args; i++) {
        cur = va_arg(valist, int);
        if(max < cur)
            max = cur;
    }
    
    va_end(valist);
    return max;
}

int min(int args, ...) {
    int i, min, cur;
    va_list valist;
    va_start(valist, args);    
    min = INT_MAX;
    
    for(i=0; i<args; i++) {
        cur = va_arg(valist, int);
        if(min > cur)
            min = cur;
    }
    
    va_end(valist);
    return min;
}
        
        
int main() 
{   
    printf("Maximum of three numbers: (10, 30, 20) = %d\n", max(3, 10, 30, 20));
    printf("Maximum of five numbers: (5, -45, 4, 60, 100) = %d\n", max(5, 5, -45, 4, 60, 100));
    
    printf("Minimum of three numbers: (5, 10, 20) = %d\n", min(3, 5, 10, 20));
    printf("Minimum of five numbers: (12, -5, 0, 10, 50) = %d\n", min(5, 12, -5, 0, 10, 50));

    printf("%s%s", "Etc", "\n");
    
    return 0;
}

//gcc mytest.c -o mytest
 
Old 04-29-2023, 12:24 PM   #11
Racho
Member
 
Registered: Oct 2021
Posts: 59

Rep: Reputation: Disabled
I came up with this:

Code:
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>

long long int llin_max(int num_args, ...) {
	va_list valist;
	int i=0;
	long long int max, new_num;
	va_start(valist, num_args);
	max = LLONG_MIN;

	for (i=0; i < num_args; i++) {
		new_num = va_arg(valist, long long int);
		max = max > new_num ? max : new_num;
	}
	va_end(valist);

	return max;
}

int countparams(char *str) {
	int i=0, j=0, len = strlen(str);
	if (len == 0)
		return 0;
	for (i=0, j=1; i <  len; i++)
		if (str[i] == ',') j++;
	return j;
}

#define lli_max(...) llin_max(countparams(#__VA_ARGS__), __VA_ARGS__);

int main() {
	long long int num=0;
	long long a= 5000;
	long long b= 500;
	num = lli_max(1,2,a, b, 300,4,5);
	printf("The greatest number is: %lli\n", num);
	return 0;
}
I tried passing an int argument to lli_max and it worked as intended but i think that it worked just because it's a 64 byte processor.

I think that an int as argument for lli_max it should fail on 32 byte processors.
Am I right?
In that case, will it compile without errors or warnings?
 
Old 04-29-2023, 12:49 PM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
On a 64-bit platform, if you pass an int (32-bit) to a variadic function, and it fetches it as long long (64-bit), it will be a single stack entry, but the result might be different to what you expect: amd64 for example leaves the upper 32 bits uninitialized.

On a 32-bit platform (e.g. x86), va_arg(ap, long long) fetches two entries from the stack.

PS: try this: lli_max((1,2),(3,4),(5,6)) - it should be equivalent with lli_max(2,4,6)

Last edited by NevemTeve; 04-30-2023 at 12:57 AM.
 
2 members found this post helpful.
Old 04-29-2023, 02:04 PM   #13
Racho
Member
 
Registered: Oct 2021
Posts: 59

Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
PS: try this: lli_max((1,2),(3,4),(5,6)) - it should be equivalent with lli_max(2,4,6)
Hmmm.... I see.. not a common way to use a function though.

This kind of thing can be fixed in the countparams function but it's annoying.

Anyway I was wondering what would happen if someone typed an int variable by mistake. It would be hard to trace that bug.

I didn't know that AMD processors would leave the upper 32 bytes uninitialized ...

Thanks for your reply!

Last edited by Racho; 04-29-2023 at 02:19 PM.
 
Old 04-29-2023, 03:56 PM   #14
Racho
Member
 
Registered: Oct 2021
Posts: 59

Rep: Reputation: Disabled
Yet another problem with this function:

The compiler defaults any numeric parameter to int if the function definition doesn't specify the type. So the user has to write long long int before every number, as shown in the code. (So annoying!)


Code:
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>

long long int llin_max(int num_args, ...) {
	va_list valist;
	int i=0;
	long long int max, new_num;
	va_start(valist, num_args);
	max = LLONG_MIN;

	for (i=0; i < num_args; i++) {
		new_num = va_arg(valist, long long int);
		max = max > new_num ? max : new_num;
	}
	va_end(valist);

	return max;
}

int countparams(char *str) {
	int i=0, j=0, parentesis=0, len = strlen(str);
	if (len == 0)
		return 0;
	for (i=0, j=1; i <  len; i++) {
		if (str[i] == ',' && !parentesis) {
			j++;
			continue;
		} 
		if (str[i] == '(') {
			parentesis ++;
			continue;
		}
		if (str[i] == ')')
			parentesis --;

	}
	return j;
}

#define lli_max(...) llin_max(countparams(#__VA_ARGS__), __VA_ARGS__);

int main() {
	long long int num=0;
	long long a = 5000;
	long long b = 77500;
	long long c = -583;
	/* The definition doesn't tell the compiler the type of va_arg arguments
	 * so it defauts any number to int */

	num = lli_max(a, b, c);	// works as intended, every argument is lli
	printf("The greatest number is: %lli\n", num);

	num = lli_max(-80,17,18, 32);	// Doesn't work: arguments are int
	printf("The greatest number is: %lli\n", num);

	num = lli_max((long long int) -80,(long long int) 17,(long long int) 18,
		       	(long long int) 32);	// Now works

	printf("The greatest number is: %lli\n", num);
	return 0;
}
Is there any other way to mess the number of parameters?
By the way, I don't know the meaning of a parameter like (3,4).
 
Old 04-30-2023, 01:04 AM   #15
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
https://en.m.wikipedia.org/wiki/Comma_operator
Counting the commas it slow and not universal solution. How about using an array?
Code:
{
    long long arr[] = { values };
    size_t narr= (sizeof arr)/(sizeof arr[0]);
    maxval= maxfun (narr, arr);
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting output of one function into array and feed value into variable in other function in ruby Sivagurunathan Programming 3 11-23-2021 09:38 AM
[SOLVED] Threaded function cannot call a function with extern "C" but nonthreaded function can morty346 Programming 16 01-12-2010 05:00 PM
AWK a variable Ouptut to a new variable and using the new variable with the old one alertroshannow Linux - Newbie 4 02-16-2009 12:08 AM
function showing a list of variable and value: (dynamic variable name) budhax Linux - Newbie 1 09-19-2008 07:05 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration